在Kotlin有一个相当于Swift代码下面?

if let a = b.val {

} else {

}

当前回答

我的答案完全是抄袭别人的。但是,我不容易理解他们的表情。所以我想提供一个更容易理解的答案会很好。

迅速:

if let a = b.val {
  //use "a" as unwrapped
}
else {

}

在芬兰湾的科特林:

b.val?.let{a -> 
  //use "a" as unwrapped
} ?: run{
  //else case
}

其他回答

上面有两个答案,都得到了很多人的接受:

str ?。让{}?:运行{} str ?。还有{}?:run {}

两者似乎都适用于大多数用法,但#1在下面的测试中会失败:

第二条似乎更好。

下面是如何只在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"
}

让我们首先确保我们理解了所提供的Swift习语的语义:

if let a = <expr> {
     // then-block
}
else {
     // else-block
}

它的意思是:“如果<expr>结果为非nil可选,则输入then块,并将符号a绑定到未包装的值。否则进入else块。

特别注意,a只在then块内绑定。在Kotlin中,您可以通过调用很容易地得到这个

<expr>?.also { a ->
    // then-block
}

你可以像这样添加一个else-block:

<expr>?.also { a ->
    // then-block
} ?: run {
    // else-block
}

这将导致与Swift习惯用法相同的语义。

如果让我们使用内联的乐趣,我们可以得到像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 ")
        }

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语句。