Nil-Coalescing运算符没有改变值

时间:2017-10-30 18:00:18

标签: swift optional swift4

Nil-Coalescing Operators是我最喜欢Swift的东西之一。由于对Swift非常熟悉,我遇到了一些不同的特殊情况。一个是我想为变量分配Optional值的地方,否则什么也不做。我目前看到两种方法:

var a : String?
var b : String?

// Possibly assign a non-nil value to a and/or b

/* First Way */
a = b ?? a

/* Second Way */
if let b = b {
    a = b
}

在这种情况下,似乎第一种方式可能很好,但是当变量得到更长的名称如mapViewController.destinationCardTitle时,第一种方式可能会变得很长。我也不能将a的值分配给nil或空String,因为如果它已包含非零值且b = nil,我不会想要更改a

的值

我想知道是否有办法在没有写a两次的情况下基本完成以下操作。

a = b ?? a

3 个答案:

答案 0 :(得分:3)

您可以设计自己的中缀运算符:

infix operator ?=
func ?=<T>(lhs: inout T, rhs: T?) {
    lhs = rhs ?? lhs
}

var a = "a"
var b: String? = "b"

a ?= b

print(a)  // "b\n"

答案 1 :(得分:2)

由于您关注的是长变量名称,让我们看一下使用长变量名称的可能性:

零 - 结合:

{{::someobject.property}}

如果-让:

aLongVariableName = bCrazyLongVariableName ?? aLongVariableName

如果比零:

if let x = bCrazyLongVariableName {
    aLongVariableName = x
}

在这三个可能的选项中,if bCrazyLongVariableName != nil { aLongVariableName = bCrazyLongVariableName } 是最短的代码量,因为每个长变量名只显示一次。但是你有if let和花括号的开销。因此,您需要具有足够长的变量名称来抵消额外的语法。

就个人而言,可读性比长度更重要。复制和粘贴意味着更少的打字。因此,使用if let x =是更好的解决方案。它的意图更清晰。

您询问了使用??避免第二个a的方法。你不能。没有其他语法可以提供您正在寻找的真正快捷方式。

您可以编写一个函数,将??作为a参数,inout作为普通参数。

b

答案 2 :(得分:-3)

这肯定很有趣 - 这就是当你有机会充分利用Swift时。在这一个上使用大锤子:

var a: String?
var b: String?

func attempt_To_Set_A_New_Value_To_A(using b: Any?) -> String {
    if b != nil {
        guard b is String else {
            // OH no! It's not a string!!!
            return ""
        }
        // Just to make sure..
        if let bString = b as? String {
            return bString
        }
    }
    // WARNING - b is definitely nil!
    return ""
}

a = attempt_To_Set_A_New_Value_To_A(using b: b).isEmpty() ? a : attempt_To_Set_A_New_Value_To_A(using b: b) 

如果你想减少乐趣,或者你只是度过了糟糕的一天,我可能会这样写:

if b != nil { a = b }