ผู้ประกอบการตามเงื่อนไข Kotlin Ternary


คำตอบ:


617

ใน Kotlin ifคำสั่งเป็นนิพจน์ ดังนั้นรหัสต่อไปนี้เทียบเท่า:

if (a) b else c

ความแตกต่างระหว่างการแสดงออกและข้อความเป็นสิ่งสำคัญที่นี่ ใน Java / C # / JavaScript ให้ifสร้างคำสั่งซึ่งหมายความว่าจะไม่สามารถแก้ไขค่าได้ ยิ่งเป็นรูปธรรมคุณไม่สามารถกำหนดให้กับตัวแปรได้

// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c

หากคุณมาจากภาษาที่ifมีคำแถลงสิ่งนี้อาจดูผิดธรรมชาติ แต่ความรู้สึกนั้นก็จะหายไปในไม่ช้า


57
whenนอกจากนี้คุณยังสามารถใช้
bashor

5
เพียงแค่เพิ่มถ้ามันเป็นการแสดงออกแบบบูลคุณสามารถไปด้วยx = a==b
gnomeria

2
@MikeRylander ฉันได้ขยายคำตอบเพื่อให้ชัดเจน ขอบคุณที่ชี้นำสิ่งนี้
Drew Noakes

1
@AdeelAnsari ไม่มันไม่ได้ทำการแก้ไข มันแย่กว่า เปรียบเทียบสิ่งนี้ b + if (a) c else dvs. b + (c if (a) else d)หลังหนึ่งต้องการวงเล็บเพิ่มเติม เพราะไม่ได้ถูกล้อมรอบด้วยสภาพและc else
Naetmul

1
นี่คือการอภิปรายเล็กน้อยเกี่ยวกับหัวข้อนี้ Discuss.kotlinlang.org/t/ternary-operator/2116/141
F. Norbert

70

คุณสามารถกำหนดBooleanฟังก์ชั่นส่วนขยายของคุณเองที่ส่งกลับnullเมื่อBooleanคือfalseการให้โครงสร้างคล้ายกับผู้ประกอบการที่ประกอบไปด้วย:

infix fun <T> Boolean.then(param: T): T? = if (this) param else null

สิ่งนี้จะทำให้การa ? b : cแสดงออกเป็นa then b ?: cเช่น:

println(condition then "yes" ?: "no")

อัปเดต: แต่หากต้องการสลับเงื่อนไขแบบคล้าย Java คุณจะต้องมีสิ่งนั้น

infix fun <T> Boolean.then(param: () -> T): T? = if (this) param() else null

println(condition then { "yes" } ?: "no") ให้ความสนใจกับแลมบ์ดา คำนวณเนื้อหาควรจะเลื่อนออกไปจนกว่าเราจะตรวจสอบให้แน่ใจconditionคือtrue

อันนี้ดูเงอะงะนั่นคือเหตุผลที่มีคำขอที่มีความต้องการสูงในการพอร์ตผู้ประกอบการที่สามของจาวาเข้าไปใน Kotlin


1
infix inline fun<T> Boolean.then(param: ()->T):T? = if(this) param() else null
nullbyte

3
ใช้ <T: ใด ๆ > มิฉะนั้นจะทำงานไม่ถูกต้อง:true then { null } ?: "not-null"
Eugene Petrenko

BTW ?:ผู้ดำเนินการที่นี่คือelvis-operator: kotlinlang.org/docs/reference/null-safety.html#elvis-operator
Eric Wang

64

TL; DR

if (a) b else c

คือสิ่งที่คุณสามารถใช้แทนนิพจน์ตัวดำเนินการแบบไตรa ? b : cภาค


ใน Kotlin งบจำนวนมากรวมทั้งการควบคุมif, whenหรือแม้กระทั่งtryสามารถใช้เป็นสำนวนที่ ซึ่งหมายความว่าสิ่งเหล่านั้นสามารถมีผลลัพธ์ที่สามารถกำหนดให้กับตัวแปรส่งคืนจากฟังก์ชัน ฯลฯ

วากยสัมพันธ์ไม่จำเป็นสำหรับผู้ประกอบการที่สาม

เป็นผลมาจากการแสดงออกของ Kotlin ภาษาไม่จำเป็นต้องดำเนินการประกอบไปด้วย

if (a) b else c

คือสิ่งที่คุณสามารถใช้แทนนิพจน์ตัวดำเนินการแบบไตรa ? b : cภาค

ฉันคิดว่าความคิดคือการแสดงออกในอดีตนั้นสามารถอ่านได้มากขึ้นเนื่องจากทุกคนรู้ว่าสิ่งifelseใดในขณะที่? :ค่อนข้างชัดเจนถ้าคุณไม่คุ้นเคยกับไวยากรณ์อยู่แล้ว

อย่างไรก็ตามฉันต้องยอมรับว่าฉันมักจะพลาดผู้ประกอบการที่สะดวกมากขึ้น


ทางเลือกอื่น ๆ

เมื่อไหร่

คุณอาจเห็นwhenโครงสร้างที่ใช้ใน Kotlin เมื่อตรวจสอบเงื่อนไข นอกจากนี้ยังเป็นวิธีในการแสดงให้เห็นว่ามีน้ำตกอื่นในทางเลือก ต่อไปนี้สอดคล้องกับตัวอย่าง OTs

when(a) {
    true -> b
    false -> c
}

ส่วนขยาย

เป็นตัวอย่างที่ดีหลายอย่าง ( ผู้ประกอบการเงื่อนไข Kotlin Ternary ) ในคำตอบอื่น ๆ ที่แสดงนามสกุลยังสามารถช่วยในการแก้กรณีการใช้งานของคุณ


36

สำหรับตัวฉันเองฉันใช้ฟังก์ชั่นส่วนขยายต่อไปนี้:

fun T?.or<T>(default: T): T = if (this == null) default else this 
fun T?.or<T>(compute: () -> T): T = if (this == null) compute() else this

คนแรกจะกลับมาให้ค่าเริ่มต้นให้ในกรณีที่วัตถุเท่ากับโมฆะ ประการที่สองจะประเมินการแสดงออกที่ให้ไว้ในแลมบ์ดาในกรณีเดียวกัน

การใช้งาน:

1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }

ส่วนตัวฉันรหัสข้างต้นอ่านได้ง่ายกว่าการifก่อสร้างแบบอินไลน์


34
มันไม่ได้ว่าเกี่ยวข้องกับคำถาม แต่ทำไมไม่ใช้:ที่เอลวิสผู้ประกอบการ ? e.getMessage() ?: "unknown"ฟังก์ชั่นแรกจะถูกแทนที่ด้วย ที่สองสามารถแสดงเป็นobj?.lastMessage?.timestamp ?: { Date() }()
ฮอต

1
@hotkey ไม่มีจุดประสงค์พิเศษสำหรับสิ่งนั้น จากมุมมองของฉันมันดูมีความสอดคล้องและมีเสียงรบกวนน้อยลงในการปฏิบัติการลูกโซ่เนื่องจากคุณไม่ควรห่อสิ่งก่อสร้างไว้ในวงเล็บ
ruX

14
@ruX ตัวดำเนินการ elvis นั้นมีลักษณะเฉพาะสำหรับเรื่องนี้และการใช้งานของคุณค่อนข้างผิดปกติ
Jayson Minard

6
ในขณะที่: ไม่เป็นไรเราไม่ไปไกลเกินถนนไปจนถึง Perl
Richard Haven

29

Java ที่เทียบเท่ากับผู้ประกอบการที่ประกอบไปด้วยสามส่วน

a ? b : c

เป็น IF ง่ายๆใน Kotlin ในหนึ่งบรรทัด

if(a) b else c

ไม่มีผู้ประกอบการที่สาม (เงื่อนไข? แล้ว: อื่น ๆ ) เพราะธรรมดาถ้าทำงานได้ดีในบทบาทนี้

https://kotlinlang.org/docs/reference/control-flow.html#if-expression


กรณีพิเศษสำหรับการเปรียบเทียบค่า Null

คุณสามารถใช้ตัวดำเนินการ Elvis

if ( a != null ) a else b
// equivalent to
a ?: b

28

นอกจากนี้ยังไม่มีการดำเนินการ ternaryใน Kotlin เป็นif elseค่าตอบแทนที่บล็อก

ดังนั้นคุณสามารถทำได้: val max = if (a > b) a else b แทนที่จะเป็นจาวาmax = (a > b) ? b : c

เรายังสามารถใช้การwhenก่อสร้างมันยังคืนค่า:

val max = when(a > b) {
    true -> a
    false -> b
}

นี่คือลิงค์สำหรับเอกสาร kotlin: การควบคุมการไหล: ถ้า, เมื่อ, สำหรับ, ในขณะที่


27

ใน Kotlin ifคือนิพจน์คือมันส่งคืนค่า ดังนั้นจึงไม่มีผู้ประกอบการที่สาม(condition ? then : else)เพราะปกติถ้าทำงานได้ดีในบทบาทนี้ แหล่งคู่มือจากที่นี่

// Traditional usage 
var max = a 
if (a < b) max = b

// With else 
var max: Int
if (a > b) {
    max = a
} else {
    max = b
}

// As expression 
val max = if (a > b) a else b

26

บางกรณีมุมไม่ได้กล่าวถึงในคำตอบอื่น ๆ

เนื่องจากการปรากฏตัวของtakeIfในKotlin 1.1ผู้ประกอบการที่สามa ? b : cสามารถแสดงเช่นนี้:

b.takeIf { a } ?: c

มันจะยิ่งสั้นลงในกรณีที่ c คือnull:

b.takeIf { a }

นอกจากนี้โปรดทราบว่าโดยทั่วไปใน Java การตรวจสอบโมฆะโลกเช่นvalue != null ? value : defaultValueแปลในอุดมคติ Kotlin เป็นเพียงvalue ?: defaultValueเพียง

ที่คล้ายกันสามารถแปลa != null ? b : ca?.let { b } ?: c


6
เป็นวิธีการb.takeIf { a } ?: cที่สั้นกว่าและสามารถอ่านได้มากกว่าif (a) b else c? ผู้ประกอบการ Terneray เป็นคุณลักษณะที่ขาดหายไปใน Kotlin เนื่องจากชื่อตัวแปรและเงื่อนไขอาจยาวและทำให้คุณแยกบรรทัดที่ไม่ดีออก
Javad Sadeqzadeh

1
ควรบันทึกไว้ด้วยว่าtakeIfจะประเมินกรณีจริงเสมอ (ที่นี่a) ไม่เพียง แต่อาจแสดงออกคำนวณเก้อถ้าaเกิดขึ้นจะเป็นเท็จ if (a is Int) { a + 3 }แต่คุณไม่สามารถได้รับประโยชน์จากมันได้ปลดเปลื้องสมาร์ทลา
TheOperator

@TheOperator ผิด { a }เป็นแลมบ์ดาที่ประเมินอย่างเฉื่อยชา
Vadzim

1
ฉันเขียนมันผิดควร "ประเมินกรณีจริง (ที่นี่b) เสมอ" แต่แม้{ a }ในขณะที่ขี้เกียจจะต้องได้รับการประเมินเพื่อกำหนดผลลัพธ์ของการแสดงออก
TheOperator

24

ดูเอกสาร :

ใน Kotlin ถ้ามีการแสดงออกคือมันจะส่งกลับค่า ดังนั้นไม่มีผู้ประกอบการที่สาม (เงื่อนไข? แล้ว: อื่น ๆ ) เพราะธรรมดาถ้าทำงานได้ดีในบทบาทนี้



12

งาน :

ลองพิจารณาตัวอย่างต่อไปนี้:

if (!answer.isSuccessful()) {
    result = "wrong"
} else {
    result = answer.body().string()
}
return result

เราต้องการสิ่งที่เทียบเท่าใน Kotlin:

return (! answer.isSuccessful ()) ? "ผิด" : answer.body (). string ()


แนวทางแก้ไข :

1. ก . คุณสามารถใช้if-expressionใน Kotlin:

return if (!answer.isSuccessful()) "wrong" else answer.body().string()

1.b มันจะดีกว่านี้มากถ้าคุณพลิกif-expression(ทำโดยไม่ทำnot):

return if (answer.isSuccessful()) answer.body().string() else "wrong"

2 . ผู้ดำเนินการ Elvis ของ Kotlin ?:สามารถทำงานได้ดียิ่งขึ้น:

return answer.body()?.string() ?: "wrong"

3 . หรือใช้คลาสที่Extension functionสอดคล้องAnswerกัน:

fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null

4 . การใช้รหัสExtension functionคุณสามารถลดได้ด้วยElvis operator:

return answer.bodyOrNull()?.string() ?: "wrong"

5 . หรือเพียงแค่ใช้whenโอเปอเรเตอร์:

when (!answer.isSuccessful()) {
    parseInt(str) -> result = "wrong"
    else -> result = answer.body().string()
}

หวังว่านี่จะช่วยได้


11

เมื่อแทนที่ผู้ควบคุมสวิตช์ของภาษา C-like ในรูปแบบที่ง่ายที่สุดดูเหมือนว่านี้

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x is neither 1 nor 2")
    }
}

3
จริง แต่ตัวอย่างที่คุณแสดงนั้นwhenเป็นคำสั่งไม่ใช่นิพจน์ การเปรียบเทียบที่เกี่ยวข้องมากขึ้นกับนิพจน์เงื่อนไขแบบไตรภาคจะทำให้แต่ละสาขาส่งคืนค่าเช่นว่าเมื่อนิพจน์ประเมินค่า (ตามที่เกิดขึ้นกับเงื่อนไขแบบไตรภาค)
Drew Noakes

9

ไม่มีผู้ประกอบการที่สามใน Kotlin ดูเหมือนว่ามีปัญหาเมื่อเห็นอย่างรวดเร็วครั้งแรก แต่คิดว่าเราสามารถทำได้ด้วย inline ถ้ามีคำสั่งอื่นเพราะนี่คือการแสดงออกที่นี่ เพียงแค่เราต้องทำ -

var number = if(n>0) "Positive" else "Negetive"

ที่นี่เราสามารถทำได้ถ้าบล็อกมากเกินไปตามที่เราต้องการ ชอบ-

var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"

ดังนั้นบรรทัดนี้จึงง่ายและอ่านได้ง่ายกว่าโอเปอร์เรเตอร์ที่ประกอบไปด้วย เมื่อเราใช้โอเปอเรเตอร์มากกว่าหนึ่งตัวในจาวาดูเหมือนว่าน่ากลัว แต่ที่นี่เรามีไวยากรณ์ที่ชัดเจน แม้ว่าเราจะสามารถเขียนเป็นหลายบรรทัดได้เช่นกัน


9

คุณสามารถใช้var a= if (a) b else cแทนผู้ประกอบการที่สาม

อีกแนวคิดที่ดีของ kotlin ก็คือ Elvis operater คุณไม่จำเป็นต้องตรวจสอบค่าว่างทุกครั้ง

val l = b?.length ?: -1

นี่จะคืนค่าความยาวถ้า b ไม่เป็นโมฆะมิฉะนั้นจะเรียกใช้งานคำสั่งด้านขวา


7

ตามที่ Drew Noakes, kotlin ใช้ถ้าคำสั่งเป็น expression ดังนั้น Ternary Conditional Operator ไม่จำเป็นอีกต่อไป

แต่ด้วยฟังก์ชั่นส่วนขยายและการโหลดล้นคุณสามารถใช้มันด้วยตัวเองนี่คือตัวอย่าง

infix fun <T> Boolean.then(value: T?) = TernaryExpression(this, value)

class TernaryExpression<out T>(val flag: Boolean, val truly: T?) {
    infix fun <T> or(falsy: T?) = if (flag) truly else falsy
}

จากนั้นใช้แบบนี้

val grade = 90
val clazz = (grade > 80) then "A" or "B"

อาจลบ <T> ดีกว่า? infix fun หรือ (falsy: T?) = ถ้า (ตั้งค่าสถานะ) เป็นเท็จอย่างอื่น
โซโล่

1
แต่เพิ่ม <T> สามารถทำให้มันทำงาน: (เกรด> 80) จากนั้นเป็นโมฆะหรือ "B"
solo

นี่มันเจ๋งจริงๆฉันจะใช้มัน: P แต่อย่าลืมว่าถ้าฉันเข้าใจผิดมันจะทำให้การจัดสรรวัตถุทุกครั้งที่มันถูกเรียก ไม่ใช่เรื่องใหญ่อะไร แต่ควรค่าแก่การได้รู้ว่ามันไม่ใช่สิ่งที่เป็นนามธรรม
Adam

6

อีกวิธีที่น่าสนใจคือการใช้when:

when(a) {
  true -> b
  false -> b
}

สามารถค่อนข้างมีประโยชน์ในบางสถานการณ์ที่ซับซ้อนมากขึ้น และจริงๆแล้วมันอ่านง่ายกว่าสำหรับฉันมากกว่าif ... else ...


6

คุณสามารถทำได้หลายวิธีใน Kotlin

  1. ใช้ถ้า

    if(a) b else c
  2. ใช้เมื่อไหร่

    when (a) { 
        true -> print("value b") 
        false -> print("value c") 
        else -> {  
            print("default return in any other case") 
        } 
    }
  3. ปลอดภัยเป็นศูนย์

    val a = b ?: c

5

ไม่มีการดำเนินงานที่สามใน Kotlin แต่มีวิธีสนุก ๆ ที่จะแก้ไข ดังที่คนอื่น ๆ ชี้ให้เห็นการแปลโดยตรงไปยัง Kotlin จะมีลักษณะเช่นนี้:

val x = if (condition) result1 else result2

แต่โดยส่วนตัวแล้วฉันคิดว่ามันอาจจะรกไปหน่อยและอ่านยาก มีตัวเลือกอื่น ๆ ในห้องสมุด คุณสามารถใช้ takeIf {} กับตัวดำเนินการ elvis:

val x = result1.takeIf { condition } ?: result2

สิ่งที่เกิดขึ้นนั่นคือคำสั่ง takeIf {} ส่งคืนผลลัพธ์ของคุณ 1 หรือ null และตัวดำเนินการ elvis จัดการตัวเลือก null มีตัวเลือกเพิ่มเติมตัวอย่างเช่น TakeUnless {}:

val x = result1.takeUnless { condition } ?: result2

ภาษาชัดเจนคุณรู้ว่ากำลังทำอะไร

หากเป็นเงื่อนไขที่ใช้กันโดยทั่วไปคุณสามารถทำสิ่งสนุก ๆ เช่นใช้วิธีการขยายแบบอินไลน์ สมมติว่าเราต้องการติดตามคะแนนเกมเป็น Int และเราต้องการส่งกลับ 0 เสมอหากเงื่อนไขไม่ได้รับ:

inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this     

ตกลงว่าน่าเกลียด แต่ให้พิจารณาว่ามันมีลักษณะอย่างไรเมื่อใช้งาน:

var score = 0
val twoPointer = 2
val threePointer = 3

score += twoPointer.zeroIfFalse { scoreCondition } 
score += threePointer.zeroIfFalse { scoreCondition } 

อย่างที่คุณเห็น Kotlin มีความยืดหยุ่นอย่างมากในการเลือกรหัสของคุณ มีตัวอย่างมากมายของฉันและอาจเป็นไปได้ว่าฉันยังไม่ได้ค้นพบ ฉันหวังว่านี่จะช่วยได้!


takeIfเป็นตัวเลือกที่ชื่นชอบแน่นอนหรูหรามาก
Javier Mendonça

4

จำผู้ประกอบการ Ternaryและผู้ดำเนินการElvisแยกความหมายในKotlinซึ่งแตกต่างจากภาษายอดนิยมจำนวนมาก การทำexpression? value1: value2จะให้คุณคำพูดที่ไม่ดีโดยKotlinคอมไพเลอร์ซึ่งแตกต่างจากภาษาอื่น ๆ ที่มีอยู่ไม่มีผู้ประกอบ ternary ใน Kotlinเป็นที่กล่าวถึงในเอกสารอย่างเป็นทางการ เหตุผลก็คือประโยคif, when and try-catch จะส่งคืนค่าเอง

ดังนั้นการทำexpression? value1: value2สามารถถูกแทนที่ด้วย

val max = ถ้า (a> b) พิมพ์ ("เลือก a") พิมพ์อื่น ("เลือก b")

ผู้ประกอบการเอลวิสที่Kotlinได้ทำงานเฉพาะในกรณีของตัวแปร nullable อดีต .:

ถ้าผมทำสิ่งที่ชอบvalue3 = value1 ?: value2แล้วถ้าvalue1เป็นโมฆะแล้วvalue2จะกลับมิฉะนั้นค่า 1จะถูกส่งกลับ

ความเข้าใจที่ชัดเจนมากขึ้นสามารถทำได้จากคำตอบเหล่านี้


3

คุณสามารถใช้ifนิพจน์สำหรับสิ่งนี้ได้ใน Kotlin ใน Kotlin ifคือนิพจน์ที่มีค่าผลลัพธ์ ดังนั้นใน Kotlin เราสามารถเขียนได้

fun max(a: Int, b: Int) = if (a > b) a else b

และใน Java เราสามารถบรรลุเหมือนกัน แต่ด้วยรหัสขนาดใหญ่

int max(int a, int b) {
return a > b ? a : b
}

2

หากคุณไม่ได้ใช้สัญกรณ์มาตรฐานคุณสามารถสร้าง / จำลองโดยใช้infixกับสิ่งนี้:

สร้างคลาสเพื่อเก็บเป้าหมายและผลลัพธ์ของคุณ:

data class Ternary<T>(val target: T, val result: Boolean)

สร้างฟังก์ชั่น infix เพื่อจำลองการทำงานแบบไตรภาค

infix fun <T> Boolean.then(target: T): Ternary<T> {
    return Ternary(target, this)
}

infix fun <T> Ternary<T>.or(target: T): T {
    return if (this.result) this.target else target
}

จากนั้นคุณจะสามารถใช้มันได้เช่นนี้:

val collection: List<Int> = mutableListOf(1, 2, 3, 4)

var exampleOne = collection.isEmpty() then "yes" or "no"
var exampleTwo = (collection.isNotEmpty() && collection.contains(2)) then "yes" or "no"
var exampleThree = collection.contains(1) then "yes" or "no"

เพื่อให้มันเทียบเท่ากับผู้ประกอบการที่เกิดขึ้นจริงอย่างสมบูรณ์ค่าเป้าหมายยังสามารถเป็นแลมบ์ดาที่ส่ง T
Old Man of Aran

1

อีกแนวทางสั้น ๆ ในการใช้งาน

val value : String = "Kotlin"

value ?: ""

ที่นี่ kotlin ตรวจสอบตัวเองเป็นโมฆะและถ้าเป็นโมฆะ


1

ทำไมคนเราจะใช้สิ่งนี้:

when(a) {
  true -> b
  false -> b
}

เมื่อคุณสามารถใช้บางสิ่งเช่นนี้ ( aเป็นบูลีนในกรณีนี้):

when {
  a -> b
  else -> b
}

1
เพราะคนแรกมีความหมายที่ชัดเจนและเข้าใจง่ายสำหรับคนอื่นที่อ่านมันแม้ว่าพวกเขาจะไม่คุ้นเคยกับ Kotlin ในขณะที่คนที่สองไม่ใช่
mc01

1
ดีคุณมีจุด แต่ฉันไม่สามารถเข้าใจว่าทำไมนักพัฒนา Kotlin ไม่แนะนำการแสดงออกที่สาม
ZZ 5

ฉันคิดว่า? and :ขัดแย้งกับการประกาศเป็นโมฆะ / ประเภทมากกว่าการตรวจสอบประเภท นอกเหนือจากนั้นฉันไม่เห็นเหตุผลใด ๆ ฉันคิดว่าบางคนจะใส่ความคิดบางอย่างแน่นอนถ้ามีการตรวจสอบแบบอินไลน์ถ้า - อื่นเงื่อนไข มาดูกันในรุ่นอนาคตกันดีกว่า
bh4r4th

1

เมื่อทำงานกับการใช้ () ให้ดูเหมือนว่ามีประโยชน์มากเมื่อจัดการกับการดำเนินการแบบไตรภาคเนื่องจากมันมีความหรูหราและให้ห้องคุณ

val columns: List<String> = ...
val band = Band().apply {
    name = columns[0]
    album = columns[1]
    year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}

0

ด้วยฟังก์ชั่น infix ต่อไปนี้ฉันสามารถครอบคลุมกรณีการใช้งานทั่วไปได้หลายอย่างในแบบเดียวกับที่มันสามารถทำได้ใน Python:

class TestKotlinTernaryConditionalOperator {

    @Test
    fun testAndOrInfixFunctions() {
        Assertions.assertThat(true and "yes" or "no").isEqualTo("yes")
        Assertions.assertThat(false and "yes" or "no").isEqualTo("no")

        Assertions.assertThat("A" and "yes" or "no").isEqualTo("yes")
        Assertions.assertThat("" and "yes" or "no").isEqualTo("no")

        Assertions.assertThat(1 and "yes" or "no").isEqualTo("yes")
        Assertions.assertThat(0 and "yes" or "no").isEqualTo("no")

        Assertions.assertThat(Date() and "yes" or "no").isEqualTo("yes")
        @Suppress("CAST_NEVER_SUCCEEDS")
        Assertions.assertThat(null as Date? and "yes" or "no").isEqualTo("no")
    }
}

infix fun <E> Boolean?.and(other: E?): E? = if (this == true) other else null
infix fun <E> CharSequence?.and(other: E?): E? = if (!(this ?: "").isEmpty()) other else null
infix fun <E> Number?.and(other: E?): E? = if (this?.toInt() ?: 0 != 0) other else null
infix fun <E> Any?.and(other: E?): E? = if (this != null) other else null
infix fun <E> E?.or(other: E?): E? = this ?: other

0

ไม่มีผู้ประกอบการที่สามใน Kotlin ที่ปิดมากที่สุดคือด้านล่างทั้งสองกรณี

  • ถ้าเป็นคำสั่ง expression

val a = true if(a) print("A is true") else print("A is false")

  • ผู้ประกอบการ Elvis

หากนิพจน์ทางด้านซ้ายของ?: ไม่ใช่โมฆะตัวดำเนินการ elvis จะส่งกลับมิฉะนั้นจะส่งคืนนิพจน์ทางด้านขวา โปรดทราบว่านิพจน์ทางด้านขวาจะได้รับการประเมินเฉพาะในกรณีที่ด้านซ้ายเป็นโมฆะ

 val name = node.getName() ?: throw IllegalArgumentException("name expected")

เอกสารอ้างอิง


0

ตัวอย่าง: var energy: Int = data? .get (position) ?. energy? .toInt ()?: 0

ใน kotlin ถ้าคุณใช้ ?: มันจะทำงานอย่างไรถ้าคำสั่งจะคืนค่า null แล้ว ?: 0มันจะใช้ 0 หรืออะไรก็ตามที่คุณเขียนด้านนี้


-1

ใน Kotlin คุณสามารถใช้การดำเนินการแบบไตรภาคเช่นนี้: val x = if(a) "add b" else "add c"


1
คำถามนี้ได้รับคำตอบเพียงพอแล้วและยังไม่ได้รับการปรับปรุงล่าสุด ไม่จำเป็นต้องโพสต์ในขณะนี้คำตอบอื่นที่ไม่แตกต่างจากคำตอบก่อนหน้า
Headcracker

-2

หลังจากการวิจัยความคิดอื่น ๆ ฉันได้รับผู้ประกอบการที่ประกอบไปด้วย:

infix fun <T : Any> Boolean.yes(trueValue: T): T? = if (this) trueValue else null
infix fun <T : Any> T?.no(falseValue: T): T = this ?: falseValue

ตัวอย่าง (เรียกใช้ที่นี่ ):

fun main() {
    run {
        val cond = true
        val result = cond yes "True!" no "False!"
        println("ternary test($cond): $result")
    }
    run {
        val cond = false
        val result = cond yes "True!" no "False!"
        println("ternary test($cond): $result")
    }
}

รุ่นนี้คล่องแคล่วและไม่ขัดแย้งกับตัวดำเนินการรวมศูนย์ว่าง


นี้เป็นชนิดของเช่นเดียวกับคำตอบที่เบี่ยงเบนของที่มันชื่อแทนthen yes
Ry-

@ ใช่ใช่และฉันไม่แน่ใจว่าพวกเขาเป็นคนเดียวกัน แต่ความคิดที่จะใช้วิธีการมัดด้วยตัวเลือกมาจากฟอรั่ม Kotlin สิ่งที่ฉันไม่ได้เห็นคือวิธี 'ไม่' ที่ฉันเกิดขึ้นเพราะฉันพบว่าการใช้ตัวดำเนินการรวมกันเป็นโมฆะทำให้เกิดความสับสนเนื่องจากเครื่องหมายคำถามอยู่หลังเครื่องหมาย 'หลังจากค่าแล้ว' แทนเงื่อนไขเหมือนในภาษาส่วนใหญ่
Bryan W. Wagner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.