Answers:
您可以let
像这样使用-function:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
请注意,run
仅在需要代码块时才需要调用该函数。run
如果您仅在Elvis-operator(?:
)之后只有一个衬垫,则可以删除-block 。
请注意,run
如果b
为null或let
-block的结果为,则将对该块进行评估null
。
因此,您通常只需要一个if
表达式。
val a = if (b == null) {
// ...
} else {
// ...
}
在这种情况下,else
-block仅在b
不为null时被评估。
a
没有的范围内定义还let
和run
。但是您可以使用隐式参数访问b
内部的值。我猜这达到了相同的目的。let
it
a
这些代码块之前的分配。并且a
可以在里面访问。
a
什么?如果是b
,则it
可以达到完全相同的目的。它是否a
使用val
-block 的结果重新分配?
it
从let
块内访问。let
或run
块的结果将分配给a
。结果是块中的最后一个表达式。您可以在 let
/ run
完成后使用作业,就像处理其他任何普通作业一样。
首先确保我们了解所提供的Swift习语的语义:
if let a = <expr> {
// then-block
}
else {
// else-block
}
这意味着:“如果<expr>
结果为非null可选,请输入then
-block,并将符号a
绑定到未包装的值。否则,请输入该else
块。
特别要注意的是,a
它仅在then
-block中绑定。在Kotlin中,您可以通过致电轻松获得
<expr>?.also { a ->
// then-block
}
您可以添加else
-block,如下所示:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
这导致了与Swift惯用语相同的语义。
我的回答完全是别人的模仿。但是,我不容易理解它们的表达。因此,我想提供一个更容易理解的答案会很好。
迅速:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
在Kotlin:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
let
代替代替also
意味着run
只要let
块返回null
,块就会执行,这不是我们想要的。
if let
声明。Swift的Optional Binding
(所谓的if-let
语句)用于找出可选变量是否包含值,如果是,则使该值可用作临时常量或变量。因此,Optional Binding
for if-let
语句如下:
斯威夫特的
if-let
声明:
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
在Kotlin中,就像在Swift中一样,为了避免在不期望的情况下尝试访问null值而导致崩溃,提供了一种特定的语法(例如b.let { }
第二个示例)来正确解包nullable types
:
Kotlin相当于 Swift
if-let
声明的1:
val b: Int? = null
val a = b
if (a != null) {
println("Good news!")
} else {
println("Equal to 'null' or not set")
}
/* RESULT: Equal to 'null' or not set */
let
当与安全调用运算符结合使用时,Kotlin 函数?:
提供了一种简洁的方法来处理可为空的表达式。
Swift 声明的Kotlin等效项2 (内联let函数和Elvis运算符)
if-let
:
val b: Int? = null
val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)
/* RESULT: Equal to 'null' or not set */
guard let
声明。guard-let
Swift中的语句简单而强大。它检查某种条件,如果其评估结果为假,则else
执行该语句,通常该语句将退出方法。
让我们探讨一下Swift的
guard-let
声明:
let b: Int? = nil
func testIt() {
guard let a = b else {
print("Equal to 'nil' or not set")
return
}
print("Good news!")
}
testIt()
/* RESULT: Equal to 'nil' or not set */
科特林对斯威夫特
guard-let
声明的类似影响:
与Swift不同的是,在Kotlin中,根本没有后卫声明。但是,您可以使用Elvis Operator
– ?:
获得类似的效果。
val b: Int? = 50
fun testIt() {
val a = b ?: return println("Equal to 'null' or not set")
return println("Good news!")
}
testIt()
/* RESULT: Good news! */
希望这可以帮助。
仅在name
不为null 时执行代码的方法如下:
var name: String? = null
name?.let { nameUnwrapp ->
println(nameUnwrapp) // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
println(nameUnwrapp) // printed "Alex"
}
let
,但是问题是关于被调用else
的对象是时执行的策略。Swift以更自然(可争论)的方式提供了它。但是我已经做了很多Kotlin和Swift的工作,但我希望Kotlin能够像Swift一样进行简单的包装。let
null
这是我的变体,限于非常常见的“如果不是null”情况。
首先,在某处定义它:
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
可能应该是internal
,以避免冲突。
现在,转换此Swift代码:
if let item = obj.item {
doSomething(item)
}
对此Kotlin代码:
ifNotNull(obj.item) { item ->
doSomething(item)
}
请注意,与Kotlin中的块一样,您可以删除参数并使用it
:
ifNotNull(obj.item) {
doSomething(it)
}
但是,如果块多于1-2行,则最好是明确的。
我发现这与Swift类似。
在Kotlin中,有一种类似的方法可以实现Swift的if-let样式
if (val a = b) {
a.doFirst()
a.doSecond()
}
您还可以分配多个可为空的值
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
如果可为空的值使用了1次以上,则这种方法将更适合。我认为,这从性能方面来说是有帮助的,因为可空值将仅被检查一次。
来源:Kotlin讨论
a
无法在内部访问let
和run
阻止。