Kotlin三元条件算子

Kotlin三元条件算子,kotlin,conditional-operator,Kotlin,Conditional Operator,这个表达式在Kotlin中的等价物是什么 a ? b : c 这在Kotlin中是无效的代码。在Kotlin中,如果语句是表达式,则为。因此,以下代码是等效的: if (a) b else c 这里,表达式和语句之间的区别很重要。在Java/C#/JavaScript中,if形成一条语句,这意味着它不会解析为值。更具体地说,您不能将其分配给变量 // Valid Kotlin, but invalid Java/C#/JavaScript var v = if (a) b else c 如

这个表达式在Kotlin中的等价物是什么

a ? b : c

这在Kotlin中是无效的代码。

在Kotlin中,如果语句是表达式,则为
。因此,以下代码是等效的:

if (a) b else c
这里,表达式和语句之间的区别很重要。在Java/C#/JavaScript中,
if
形成一条语句,这意味着它不会解析为值。更具体地说,您不能将其分配给变量

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

如果您来自一种语言,如果
是一种语句,这可能看起来不自然,但这种感觉很快就会消失。

对于我自己,我使用以下扩展函数:

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
就我个人而言,上面的代码比
更具可读性,如果
构造内联

请查看:

在Kotlin中,if是一个表达式,即它返回一个值。因此 没有三元运算符(条件?那么:else), 因为普通if在这个角色中工作得很好


您可以定义自己的
Boolean
扩展函数,当
Boolean
false
时,该函数返回
null
,以提供类似于三元运算符的结构:

infix fun <T> Boolean.then(param: T): T? = if (this) param else null
val x = result1.takeIf { condition } ?: result2
when (!answer.isSuccessful()) {
    parseInt(str) -> result = "wrong"
    else -> result = answer.body().string()
}
更新: 但要做更多类似Java的条件切换,您需要这样的东西

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

println(条件为{“是”}?:“否”)
注意lambda。其内容计算应推迟到我们确定
条件


当替换类C语言的开关操作符时,这个看起来很笨拙。最简单的形式是这样的

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x is neither 1 nor 2")
    }
}
val grade = 90
val clazz = (grade > 80) then "A" or "B"

在Kotlin中,
如果
是一个表达式,即返回一个值。所以 没有三元运算符
(条件?那么:else)
,因为 普通if在此角色中工作正常

//传统用法
var max=a
如果(ab){
最大值=a
}否则{
最大值=b
}
//作为表达
val max=如果(a>b)a其他b

正如Drew Noakes引用的,kotlin使用if语句作为表达式, 所以三元条件运算符不再是必需的

但使用扩展函数和中缀重载,您可以自己实现,下面是一个示例

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
}

Kotlin中没有三元运算符。乍一看,这似乎有问题。但我想我们可以用内联if-else语句来实现,因为这里是表达式。我们必须这么做-

var number = if(n>0) "Positive" else "Negetive"
在这里,如果我们需要的块太多,我们可以选择其他块。像-

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

var number=if(n>0)“肯定”else if(n其他答案中未提及的一些极端情况

因为三元运算符
a中的出现?b:c
也可以这样表示:

b.takeIf { a } ?: c
val x = if (condition) result1 else result2
when(a) {
  true -> b
  false -> b
}
val ans = (exp1 == exp2) then "yes" ?: "no"
如果c为
null
,则该值会变得更短:

b.takeIf { a }
还要注意Java世界中典型的空检查,如
value!=null?value:defaultValue
将ideomatic Kotlin转换为
value?:defaultValue

类似的
a!=null?b:c
可以翻译成
a?.let{b}?:c
Java

int temp = a ? b : c;
相当于Kotlin:

var temp = if (a) b else c

另一个有趣的方法是在以下情况下使用

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

在一些更复杂的场景中非常方便。老实说,它比
if…else…
在kotlin中没有三元运算符,因为
if else
块返回值对我来说更可读

因此,您可以:
val max=if(a>b)a else b
而不是java的
max=(a>b)?b:c

我们也可以在
构造时使用
,它还返回值:

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

下面是kotlin文档的链接:

另一种简短的使用方法

val value : String = "Kotlin"

value ?: ""

在这里,kotlin本身会检查null值,如果为null,则会传递空字符串值。

在kotlin中,您可以通过多种方式执行此操作

  • 使用if

    if(a) b else c
    
  • 何时使用

    when (a) { 
        true -> print("value b") 
        false -> print("value c") 
        else -> {  
            print("default return in any other case") 
        } 
    }
    
  • 零安全

    val a = b ?: c
    
  • 太长,读不下去了 ^是可以用来代替Kotlin语法不允许的三元运算符表达式
    a?b:c


    在Kotlin中,许多控制语句,例如
    if
    when
    ,甚至
    try
    ,都可以用作表达式。因此,这些语句可以具有一个可以分配给变量的结果,也可以从函数返回的结果,等等

    从语法上讲,不需要三元运算符 由于Kotlin的表达式,该语言实际上不需要三元运算符

    if (a) b else c
    
    是可以用来代替三元运算符表达式
    a?b:c

    我认为前一个表达式更具可读性,因为每个人都知道
    ifelse
    做什么,而
    ?:
    如果您还不熟悉语法,则相当不清楚

    然而,我不得不承认,我经常错过更方便的三元运算符


    其他备选方案

    何时

    当检查条件时,您可能还会看到Kotlin中使用的
    构造。这也是一种表示if-else以另一种方式级联的方法。以下与OTs示例相对应

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


    正如其他答案中的许多好例子()所示,扩展也有助于解决您的用例。

    通过以下中缀函数,我可以以与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
    
    类TestKotlInternalyConditionalOperator{
    @试验
    fun testAndOrInfixFunctions(){
    断言。断言(真实且“是”或“否”)。isEqualTo(“是”)
    断言。断言(错误且“是”或“否”)。isEqualTo(“否”)
    断言。断言(“A”和“是”或“否”)。isEqualTo(“是”)
    assertThat(“”和“是”
    
    int max(int a, int b) {
    return a > b ? a : b
    }
    
    val columns: List<String> = ...
    val band = Band().apply {
        name = columns[0]
        album = columns[1]
        year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
    }
    
    val x = if (condition) result1 else result2
    
    val x = result1.takeIf { condition } ?: result2
    
    val x = result1.takeUnless { condition } ?: result2
    
    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 } 
    
     val name = node.getName() ?: throw IllegalArgumentException("name expected")
    
    when(a) {
      true -> b
      false -> b
    }
    
    when {
      a -> b
      else -> b
    }
    
    val l = b?.length ?: -1
    
    if (!answer.isSuccessful()) {
        result = "wrong"
    } else {
        result = answer.body().string()
    }
    return result
    
    return if (!answer.isSuccessful()) "wrong" else answer.body().string()
    
    return if (answer.isSuccessful()) answer.body().string() else "wrong"
    
    return answer.body()?.string() ?: "wrong"
    
    fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null
    
    return answer.bodyOrNull()?.string() ?: "wrong"
    
    when (!answer.isSuccessful()) {
        parseInt(str) -> result = "wrong"
        else -> result = answer.body().string()
    }
    
    a ? b : c
    
    if(a) b else c
    
    if ( a != null ) a else b
    // equivalent to
    a ?: b
    
    data class Ternary<T>(val target: T, val result: Boolean)
    
    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"
    
    if (a>b) {
        println("a is greater than b")
        a // value of this if
    } else {
        println("b is greater than a")
        b // value of else
    }
    
    val ans = (exp1 == exp2) then "yes" ?: "no"
    
    infix fun<T> Boolean.then(first: T): T? = if (this) first else null