斯威夫特如果在科特林发表声明

时间:2017-10-13 06:25:58

标签: kotlin

在Kotlin中,是否有与下面的Swift代码等效的内容?

if let a = b.val {

}
else {

}

15 个答案:

答案 0 :(得分:168)

您可以使用let - 这样的功能:

val a = b?.let {
    // If b is not null.
} ?: run {
    // If b is null.
}

请注意,只有在需要代码块时才需要调用run函数。如果在elvis-operator(run)之后只有一个oneliner,则可以删除?: - 块。

请注意,如果run为空,或者b - 块的评估结果为let,则会评估null块。

因此,您通常只需要一个if表达式。

val a = if (b == null) {
    // ...
} else {
    // ...
}

在这种情况下,只有在else为空时才会评估b - 块。

答案 1 :(得分:24)

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

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

这意味着:“如果<expr>导致非零可选,请输入then - 块,其中符号a绑定到未包装的值。否则输入{ {1}}阻止。

特别注意else仅在a - 块中绑定。在Kotlin,您可以通过致电

轻松获得此信息
then

你可以像这样添加<expr>?.also { a -> // then-block } - 块:

else

这导致与Swift习语相同的语义。

答案 2 :(得分:4)

以下是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"
}

答案 3 :(得分:3)

与Swift不同,在Kotlin中使用它之前,不必先将其拆开。我们只需检查该值是否为非null,编译器就会跟踪有关您执行的检查的信息,并允许将其作为未包装的内容使用。

在Swift中:

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

}

在科特林:

if b.val != null {
  //use "b.val" as unwrapped
} else {

}

有关更多此类用例,请参考Documentation: (null-safety)

答案 4 :(得分:2)

上面有两个答案,都得到了很多认可:

  1. str?。 {}吗?:运行{}
  2. str?。 {}吗?:运行{}

这两种方法似乎都可以使用,但是在以下测试中#1会失败:

enter image description here

#2似乎更好。

答案 5 :(得分:1)

我的回答完全是别人的模仿。但是,我不容易理解它们的表达。因此,我想提供一个更容易理解的答案会很好。

迅速:

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

}

在科特林:

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

答案 6 :(得分:1)

这是我的变体,仅限于非常常见的“如果不是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类似。

答案 7 :(得分:0)

if let语句。

Swift的Optional Binding(所谓的if-let语句)用于查找可选值是否包含值,如果是,则将该值用作临时常量或变量。因此,Optional Binding语句的if-let如下:

  

Swift的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 { }),用于正确解包 {{ 1}}

  

相当于Swift的nullable types语句的Kotlin 1

if-let

Kotlin的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结合使用时,提供了一种简洁的方法来处理可为空的表达式。

  Swift的?:语句的

等效于Kotlin的2 (内联let函数和Elvis运算符)

if-let

enter image description here

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

Swift中的

guard let语句简单而强大。它会检查某些条件,如果结果为假,则执行guard-let语句,该语句通常会退出方法。

  

让我们探讨一下Swift的else语句:

guard-let
  

科特林对Swift的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 */ 语句的类似影响

与Swift不同,在Kotlin中根本没有 guard 声明。但是,您可以使用guard-let Elvis Operator 来获得类似的效果。

?:

希望这会有所帮助。

答案 8 :(得分:0)

我正在添加此答案以澄清已接受的答案,因为它太大了,无法发表评论。

此处的一般模式是,您可以使用Kotlin中可用的Scope Functions的任意组合,并以Elvis Operator分隔,如下所示:

<nullable>?.<scope function> {
    // code if not null
} :? <scope function> {
    // code if null
}

例如:

val gradedStudent = student?.apply {
    grade = newGrade
} :? with(newGrade) {
    Student().apply { grade = newGrade }
}

答案 9 :(得分:0)

在Kotlin中快速查看let语句

简短的答案是使用简单的 IF-ELSE ,因为在发表此评论时,Kotlin LET中没有等效的内容,

    if(A.isNull()){
// A is null
    }else{
// A is not null
    }

答案 10 :(得分:0)

我们可以使用if let获得与Swift inline fun相同的Unwraping语法

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 ")
        }

答案 11 :(得分:0)

要像Swift if let语法一样立即解包多个变量,您可以考虑以下几行的全局实用程序函数(示例需要3个参数,但是您可以为任意数量的参数定义重载):

inline fun <A : Any, B : Any, C : Any> notNull(
    a: A?, b: B?, c: C?, perform: (A, B, C) -> Unit = { _, _, _ -> }
): Boolean {
    if (a != null && b != null && c != null) {
        perform(a, b, c)
        return true
    }
    return false
}

样品用量:

if (notNull("foo", 1, true) { string, int, boolean ->
    print("The three values were not null and are type-safe: $string, $int, $boolean")
}) else {
    print("At least one of the vales was null")
}

答案 12 :(得分:0)

如果 b 是一个成员变量,那么这种方法对我来说似乎最易读:

val b = this.b
if (b == null) {
    return
}
println("non nullable : ${b}")

这也与它在 swift 中的工作方式一致,其中一个新的局部变量隐藏了成员变量。

答案 13 :(得分:-1)

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

答案 14 :(得分:-1)

我认为最干净的选择是

迅速:

if let a = b.val {

} else {

}

科特琳

b.val.also { a ->

} ?: run {

}