Kotlin中的此表达等效于什么?
a ? b : c
这不是Kotlin中的有效代码。
Kotlin中的此表达等效于什么?
a ? b : c
这不是Kotlin中的有效代码。
Answers:
在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
,这似乎很不自然,但这种感觉很快就会消失。
when
。
x = a==b
b + if (a) c else d
vs. b + (c if (a) else d)
后者需要附加括号。因为c
没有被条件和包围else
。
你可以定义自己的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
infix inline fun<T> Boolean.then(param: ()->T):T? = if(this) param() else null
true then { null } ?: "not-null"
if (a) b else c
是您可以用来代替三元运算符的表达式a ? b : c
。
在Kotlin中,许多控制语句包括if
,when
甚至try
可以用作表达式。这意味着它们可以具有可以分配给变量,从函数返回等的结果。
由于Kotlin的表达,该语言实际上并不需要三元运算符。
if (a) b else c
是您可以用来代替三元运算符的表达式a ? b : c
。
我认为这样的想法是,由于每个人都知道它的含义,因此前一个表达式更具可读性ifelse
,而? :
如果您还不熟悉该语法,则还不清楚。
尽管如此,我不得不承认我经常想念更方便的三元运算符。
其他选择
什么时候
when
检查条件时,您可能还会看到Kotlin中使用的构造。这也是一种以其他方式表示if-else级联的方式。以下对应于OT的示例。
when(a) {
true -> b
false -> c
}
扩展名
正如其他答案中许多好的示例(Kotlin三元条件运算符)所示,扩展也可以帮助解决您的用例。
我自己使用以下扩展功能:
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
如果对象等于null,则第一个将返回提供的默认值。其次,将评估在相同情况下lambda中提供的表达式。
用法:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
就我个人而言,以上代码比if
构造内联更具可读性
e.getMessage() ?: "unknown"
。第二个可以表示为obj?.lastMessage?.timestamp ?: { Date() }()
Java相当于三元运算符
a ? b : c
是一行在Kotlin中的简单IF
if(a) b else c
没有三元运算符(条件?then:else),因为普通if在此角色下工作正常。
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
空比较的特殊情况
您可以使用猫王运算符
if ( a != null ) a else b
// equivalent to
a ?: b
有没有三元运算符在科特林,作为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文档的链接:控制流:是否,何时,何时,何时
其他答案未提及的一些极端情况。
由于takeIf在Kotlin 1.1中出现,三元运算符a ? b : c
也可以这样表示:
b.takeIf { a } ?: c
如果c为null
:
b.takeIf { a }
还要注意,在Java世界中,典型的null检查(例如,value != null ? value : defaultValue
将意识形态Kotlin中的null检查转换为just)value ?: defaultValue
。
类似的a != null ? b : c
可以翻译为a?.let { b } ?: c
。
b.takeIf { a } ?: c
比它更短,更易读if (a) b else c
?Terneray运算符无疑是Kotlin中缺少的功能,因为变量名和条件可能很长,使您
takeIf
总是评估真实情况(在此处a
)。如果a
碰巧是假的,那么该表达式不仅会被无用地计算,而且您无法从智能转换àla中受益if (a is Int) { a + 3 }
。
{ a }
是惰性评估的lambda。
b
)”。但是,即使是{ a }
懒惰的人,也必须对其求值以确定表达式的结果。
爪哇
int temp = a ? b : c;
相当于Kotlin:
var temp = if (a) b else c
任务:
让我们考虑以下示例:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
我们在Kotlin中需要以下等效项:
返回(!answer.isSuccessful())
?
“错误”的:
answer.body()。string()
解决方案:
1.A。您可以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。Kotlin的Elvis操作员?:
可以做得更好:
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()
}
希望这可以帮助。
when替换类C语言的switch运算符。以最简单的形式看起来像这样
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
when
作为声明而不是表达式。与三元条件表达式的更相关的比较是使每个分支都返回一个值,以使整个when表达式的值均等于一个值(如三元条件表达式一样)。
Kotlin中没有三元运算符。乍看起来似乎有问题。但是请认为我们可以使用内联if else语句来完成此操作,因为这是此处的表达式。只需我们要做-
var number = if(n>0) "Positive" else "Negetive"
在这里,我们可以根据需要阻塞太多。喜欢-
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
因此,这条线比三元运算符简单易读。当我们在Java中使用多个三元运算符时,这似乎很可怕。但是这里我们有一个清晰的语法。即使我们也可以将其写成多行。
正如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
}
然后像这样使用它
val grade = 90
val clazz = (grade > 80) then "A" or "B"
另一种有趣的方法是使用when
:
when(a) {
true -> b
false -> b
}
在某些更复杂的场景中可以非常方便。老实说,对我而言,它比if ... else ...
您可以在科特林做很多事情
使用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中没有三元运算,但是有一些有趣的方法可以解决此问题。正如其他人指出的那样,直接翻译成Kotlin会像这样:
val x = if (condition) result1 else result2
但是,就我个人而言,我认为这可能会有些混乱并且难以阅读。库中还内置了其他一些选项。您可以将takeIf {}与Elvis运算符配合使用:
val x = result1.takeIf { condition } ?: result2
发生的情况是takeIf {}命令返回result1或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
确实是我最喜欢的选择,非常优雅。
请记住,与许多流行语言不同,三元运算符和猫王运算符在Kotlin中具有不同的含义。这样做expression? value1: value2
会使Kotlin编译器给您带来不好的单词,这与任何其他语言都不一样,因为Kotlin中没有官方文档中提到的三元运算符。原因是if,when和try-catch语句本身返回值。
因此,expression? value1: value2
可以将其替换为
val max = if(a> b)print(“ Choose a”)else print(“ Choose b”)
该Elvis操作符是科特林了,只能在可空变量前的情况:
如果我做类似的事情,
value3 = value1 ?: value2
那么如果value1为null,则将返回value2,否则将返回value1。
从这些答案中可以获得更清晰的理解。
如果您不使用标准符号,也可以使用infix创建/模拟它,如下所示:
创建一个类来保存您的目标和结果:
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"
另一个简短的使用方法
val value : String = "Kotlin"
value ?: ""
在这里,kotlin本身会检查null值,如果为null,则它将传递空字符串值。
使用以下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
例如: var energy:Int = data?.get(position)?. energy?.toInt()?:0
在kotlin中,如果您使用 ?: 它将像语句将返回null,然后 ?:0一样工作,它将花费0或您编写此面的任何内容。
在Kotlin中,您可以使用以下三元运算: val x = if(a) "add b" else "add c"
在对其他想法进行了一些研究之后,我得出了以下三元运算符:
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
。