Kotlin中这个表达的等价物是什么?
a ? b : c
这不是Kotlin中的有效代码。
答案 0 :(得分:487)
在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
是一种陈述的语言,这可能看起来不自然,但这种感觉很快就会消退。
答案 1 :(得分:56)
您可以定义自己的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")
关注lambda。其内容计算应推迟到我们确保condition
为true
这个看起来很笨拙,that is why there is high demanded request exist to port Java ternary operator into Kotlin
答案 2 :(得分:36)
if (a) b else c
代替Java表达式a ? b : c
。
在Kotlin中,许多控制语句(包括if
,when
甚至try
都可以用作表达式。这意味着那些可以具有可以分配给变量的结果,从函数等返回。
因此, Kotlin不需要三元运算符。
您可以使用 if (a) b else c
代替Java表达式a ? b : c
。
我认为后者的可读性较差,因为每个人都知道ifelse
的作用,而? :
如果您不熟悉语法则相当不方便。虽然我不得不承认我经常会错过更方便的三元运算符。
其他替代方案
:当强>
在Kotlin中检查条件时,您可能还会看到很多when
构造。它也是一种以另一种方式表达if-else级联的方法。以下对应于您的示例。
when(a) {
true -> b
false -> c
}
<强>扩展强>
正如其他答案中的许多好例子(Kotlin Ternary Conditional Operator)所示,扩展也可以是一种方法。
答案 3 :(得分:33)
For myself I use following extension functions:
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
First one will return provided default value in case object equals null. Second will evaluate expression provided in lambda in the same case.
Usage:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
Personally for me code above more readable than if
construction inlining
答案 4 :(得分:26)
在Kotlin中,
if
是一个表达式,即它返回一个值。因此 没有三元运算符(condition ? then : else)
,因为 普通如果在这个角色中工作正常。 manual source from here
// 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
答案 5 :(得分:26)
kotlin中有没有三元运算符,因为 if else
块返回值
所以,你可以这样做:
val max = if (a > b) a else b
而不是java的max = (a > b) ? b : c
我们也可以使用 when
构造,它也会返回值:
val max = when(a > b) {
true -> a
false -> b
}
以下是kotlin文档的链接:jqGrid - determine name of column on right click of a column in jqGrid
答案 6 :(得分:22)
查看docs:
在Kotlin中,if是一个表达式,即它返回一个值。因此有 是没有三元运算符(条件?那么:其他), 因为普通如果在这个角色中工作正常。
答案 7 :(得分:21)
其他答案中未提及某些角落案例。
由于在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 : c
可以翻译为a?.let { b } ?: c
。
答案 8 :(得分:14)
Java
int temp = a ? b : c;
相当于Kotlin:
var temp = if (a) b else c
答案 9 :(得分:12)
替换C语言的switch运算符时。在最简单的形式,它看起来像这样
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
答案 10 :(得分:11)
Kotlin没有三元运营商。乍一看似乎有问题。但是我认为我们可以使用inline if else语句来实现它,因为这是表达式。我们只需做 -
var number = if(n>0) "Positive" else "Negetive"
在这里我们可以阻止我们需要的多少。象 -
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
因此,这条线比三元运算符简单易读。当我们在java中使用多个三元运算符时,它似乎很糟糕。但在这里我们有一个清晰的语法。即使我们也可以用多行编写它。
答案 11 :(得分:7)
但是使用扩展功能和中缀重载,您可以自己实现,这是一个示例
val grade = 90
val clazz = (grade > 80) then "A" or "B"
然后像这样使用它
{{1}}
答案 12 :(得分:7)
你可以在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
答案 13 :(得分:6)
另一种有趣的方法是使用when
:
when(a) {
true -> b
false -> b
}
在一些更复杂的场景中非常方便。老实说,它比我if ... else ...
答案 14 :(得分:6)
您可以使用var a= if (a) b else c
代替三元运算符。
猫王经营者是科特林的另一个很好的概念。您不必每次都检查null。
val l = b?.length ?: -1
如果b不为null,它将返回长度,否则将执行右侧语句。
答案 15 :(得分:5)
任务:
让我们考虑以下示例:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
我们在Kotlin中需要以下等价物:
返回(!answer.isSuccessful())
?
“错误”:
answer.body()。string( )
解决方案:
1.a 。您可以在Kotlin中使用if-expression
:
return if (!answer.isSuccessful()) "wrong" else answer.body().string()
1.b 。翻转此if-expression
可能会更好(让我们在没有not
的情况下这样做):
return if (answer.isSuccessful()) answer.body().string() else "wrong"
2 。科特林的猫王操作员?:
可以做得更好:
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()
}
希望这会有所帮助。
答案 16 :(得分:4)
Kotlin没有三元手术,但有一些有趣的方法可以解决这个问题。正如其他人所指出的那样,直接翻译成Kotlin会是这样的:
val x = if (condition) result1 else result2
但是,就个人而言,我认为这可能会变得有点混乱,难以阅读。库中还内置了一些其他选项。您可以将takeIf {}与elvis运算符一起使用:
val x = result1.takeIf { condition } ?: result2
正在发生的事情是takeIf {}命令返回result1或null,而elvis运算符处理null选项。还有一些其他选项,例如:unUnless {}:
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为您选择表达代码提供了很大的灵活性。我的例子有无数变化,可能还有我尚未发现的方法。我希望这有帮助!
答案 17 :(得分:3)
您可以在Kotlin中使用if
表达式。在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
}
答案 18 :(得分:3)
记住三元运算符和 Elvis运算符在 Kotlin 中具有不同的含义。 expression? value1: value2
会使 Kotlin 编译器给您带来不好的字眼,这与其他任何语言都不一样,因为{{3}中提到的Kotlin中没有没有三元运算符 }。原因是 if,when和try-catch 语句本身返回值。
因此,可以将expression? value1: value2
替换为
val max =如果(a> b) 打印(“选择一个”) 其他 print(“选择b”)
Kotlin 所具有的 Elvis运算符,仅在可空变量ex。的情况下起作用:
如果我做类似
value3 = value1 ?: value2
的操作,则如果 value1 为 null ,则将返回 value2 ,否则返回 value1 < / em>将被返回。
从official docs可以更清楚地了解。
答案 19 :(得分:2)
Kotlin没有三元运算符。您可以使用如下所示的正则if
表达式:
if (condition) exp1 else exp2
如果您在{{1}的主体内有多个语句,那么Kotlin中的if
不是语句而是表达式(即它的值) }分支(或if
或else
的主体),块的最后一行是该分支的值。例如:
else if
答案 20 :(得分:2)
为什么要使用这样的东西:
when(a) {
true -> b
false -> b
}
当您实际上可以使用类似这样的内容时(在这种情况下,a
是布尔值):
when {
a -> b
else -> b
}
答案 21 :(得分:2)
你可以这样做:
val ans = (exp1 == exp2) then "yes" ?: "no"
通过使用这个扩展:
infix fun<T> Boolean.then(first: T): T? = if (this) first else null
P.S:不要修改上面的中缀函数来接受first: T?
,表达式会在逻辑上变得不正确。例如:如果您修改它以接受可为空的 first: T?
,那么 val ans = (true == true) then null ?: "abcd"
、ans
将是 "abcd"
,这是不正确的。
答案 22 :(得分:2)
另一种使用的简短方法
val value : String = "Kotlin"
value ?: ""
这里kotlin本身检查空值,如果它为null,则它传递空字符串值。
答案 23 :(得分:1)
在Kotlin中,您可以像这样使用三元运算:$ make install
You must be root to perform this action.
$ sudo make install
TODO: The action when the user is root here...
答案 24 :(得分:1)
如果您不使用标准符号,也可以使用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"
答案 25 :(得分:0)
fun max(x:Int,y:Int):字符串= if(x> y)“ max = $ x”否则“ max = $ y”
在线功能
答案 26 :(得分:0)
在 Java 中,if 是一个语句,而在 Kotlin 中,if 是一个表达式。之所以称为表达式,是因为它比较 a 和 b 的值并返回最大值。因此,在 Kotlin 中没有三元运算符 (a>b)?a:b 因为它被 if 表达式替换了。
答案 27 :(得分:0)
如果有人需要使用隐式强制转换的三元运算符:
/**'[_t]' for ternary operator*/
@Suppress("FunctionName")
@OptIn(ExperimentalContracts::class)
fun <T> _t(bool: Boolean, onTrue: T, onFalse: T): T
{
contract { returns() implies bool }
return if (bool) onTrue else onFalse
}
尽管不确定这有什么用
答案 28 :(得分:0)
Java等价的三元运算符
a ? b : c
是Kotlin中一行的简单IF
if(a) b else c
没有三元运算符(条件?然后:else),因为 普通,如果在这个角色上工作正常。
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
答案 29 :(得分:0)
在研究了其他想法之后,我得出了以下三元运算符:
image1
示例(运行here):
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
此版本很流畅,并且与null合并运算符不冲突。
答案 30 :(得分:0)
示例:无功电能:Int = data?.get(position)?. energy?.toInt()?:0
在kotlin中,如果您正在使用?:,它将像语句将返回null然后 ?: 0 一样工作,它将花费0或您在这边写的任何内容
答案 31 :(得分:0)
Kotlin中没有三元运算符,最封闭的是以下两种情况,
{ "code": 406, "message": "Not Acceptable", "errors": [ "Invalid date range: End date is before start date." ] }
如果?:左侧的表达式不为null,则为elvis运算符 返回它,否则它返回右边的表达式。注意 仅在左侧表达式时才评估右侧表达式 side为空。
val a = true if(a) print("A is true") else print("A is false")
答案 32 :(得分:0)
使用apply()时,在处理三元操作时似乎非常方便,因为它更优雅并且给你空间
val columns: List<String> = ...
val band = Band().apply {
name = columns[0]
album = columns[1]
year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
答案 33 :(得分:0)
使用以下中缀函数,我可以覆盖许多常见用例,几乎与在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