在Kotlin有一个相当于Swift代码下面?
if let a = b.val {
} else {
}
在Kotlin有一个相当于Swift代码下面?
if let a = b.val {
} else {
}
当前回答
如果b是一个成员变量,那么这种方法对我来说似乎是最有可读性的:
val b = this.b
if (b == null) {
return
}
println("non nullable : ${b}")
这也与它在swift中的工作方式一致,在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 Discussion
如果让我们使用内联的乐趣,我们可以得到像Swift一样的unwring语法
inline fun <T:Any?> T?.unwrap(callback: (T)-> Unit) : Boolean {
return if (this != null) {
this?.let(callback)
true
}else {
false
}
}
用途::
val name : String? = null
val rollNo : String? = ""
var namesList: ArrayList<String>? = null
if (name.unwrap { name ->
Log.i("Dhiru", "Name have value on it $name")
})else if ( rollNo.unwrap {
Log.i("Dhiru","Roll have value on it")
}) else if (namesList.unwrap { namesList ->
Log.i("Dhiru","This is Called when names list have value ")
}) {
Log.i("Dhiru","No Field have value on it ")
}
下面是如何只在name不为空时执行代码:
var name: String? = null
name?.let { nameUnwrapp ->
println(nameUnwrapp) // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
println(nameUnwrapp) // printed "Alex"
}
Any的问题是什么?让{}?:运行{}结构是:
它只允许每条语句进行一次非空检查 如果let块返回null,运行块无论如何都会被求值 不可能在switch/when样式中执行多次检查
解决这些问题的一个解决方案是定义如下的函数:
private inline fun <A> ifNotNull(p1: A?, block: (A) -> Unit): Unit? {
if (p1 != null) {
return block.invoke(p1)
}
return null
}
private inline fun <A, B> ifNotNull(p1: A?, p2: B?, block: (A, B) -> Unit): Unit? {
if (p1 != null && p2 != null) {
return block.invoke(p1, p2)
}
return null
}
private inline fun <A, B, C> ifNotNull(p1: A?, p2: B?, p3: C?, block: (A, B, C) -> Unit): Unit? {
if (p1 != null && p2 != null && p3 != null) {
return block.invoke(p1, p2, p3)
}
return null
}
这将允许这样的语句:
ifNotNull(a, b) { a, b ->
// code when a, b are not null
} ?:
ifNotNull(c) { c ->
// code when a, b are null and c not null
} ?:
ifNotNull(d, e, f) { d, e, f ->
// code when a, b, c are null and d, e, f not null
} ?: run {
// code which should be performed if a, b, c, d, e and f are null
}
唯一需要注意的是,与Swift的if let相比,如果在循环中执行,则不支持continue和break语句。
上面有两个答案,都得到了很多人的接受:
str ?。让{}?:运行{} str ?。还有{}?:run {}
两者似乎都适用于大多数用法,但#1在下面的测试中会失败:
第二条似乎更好。