Swift 2:是否有一个简短的语法来有条件地从一个可选变量中设置一个非可选变量?

Swift 2: is there a short syntax to conditionally set a non-optional variable from an optional variable?

有时我发现自己写 swift 2 代码是这样的:

class Test {
    var optionalInt: Int?
    var nonOptionalInt: Int = 0
    func test() {
        if let i = optionalInt {
            nonOptionalInt = i
        }
        // do more stuff
    }
}

有问题的部分是这样的:

if let i = optionalInt {
    nonOptionalInt = i
}

言下之意: 如果 optionalInt 有值,将其赋值给变量 nonOptionalInt,否则什么也不做。

在 swift 2 中是否有等效的方法来在优雅的单行中表达这一点,而无需使用 if let i 添加中间变量?

编辑

考虑第一个答案后...

显然有一个等效的方法

if optionalInt != nil {
    nonOptionalInt = optionalInt!
}

三元运算符? : 不等价,因为它们可能会触发原始代码不会触发的 didSet(如果这是预期的副作用则很好)

迄今为止最优雅的答案似乎是

nonOptionalInt = optionalInt ?? nonOptionalInt

它也可能像三元运算符一样触发 didSet,因此不等价(如果有意的话也很好)。

我想我对 Apple 的愿​​望是这样的

nonOptionalInt = optionalInt ?? 

nonOptionalInt ??= optionalInt

Is there an equivalent way in swift 2 to express this in a elegant single line without adding an intermediate variable with if let i?

如果您愿意,可以省略中间值:

if optionalInt != nil {
    nonOptionalInt = optionalInt!
}

如果您愿意,您显然可以将所有内容放在一行中:

if optionalInt != nil { nonOptionalInt = optionalInt! }

但如果您愿意,也可以使用三元运算符:

nonOptionalInt = (optionalInt != nil) ? optionalInt! : 0

其中 0 只是在 optionalInt == nil 的情况下使用的默认值。如果您不想更改 nonOptionalInt if optionalInt == nil 则只需使用 nonOptionalInt:

nonOptionalInt = (optionalInt != nil) ? optionalInt! : nonOptionalInt

请注意 optionalInt! 中的 ! 隐式解包可选值——这是您告诉编译器您知道 optionalInt 不是 nil 的方式所以可以分配给非可选变量。

您要查找的是nil coalescing operator

在这种情况下,您可以像这样使用它:

nonOptionalInt = optionalInt ?? nonOptionalInt

编辑

回复:您对问题的最后编辑:

"我想我对 Apple 的愿​​望是这样的 nonOptionalInt ??= optionalInt"

...为什么希望什么时候能建好呢? :)

我还没有充分考虑来决定我是否会为一般情况推荐这样的东西,但如果它对你的情况有帮助,你可以创建一个 ??= 运算符来完成你的要求这个:

infix operator ??= {}

func ??= <T>(inout lhs: T, rhs: T?) -> Void {
  guard let value = rhs else { return }
  lhs = value
}

然后,看看实际效果:

let optionalNil: String? = nil,
  optionalValue: String? = "optionalValue",
  implicitlyUnwrappedNil: String! = nil,
  implicitlyUnwrappedValue: String! = "implicitlyUnwrappedValue"
var a = "a", b = "b", c = "c", d = "d"

a ??= optionalNil               // "a"
b ??= optionalValue             // "optionalValue"
c ??= implicitlyUnwrappedNil    // "c"
d ??= implicitlyUnwrappedValue  // "implicitlyUnwrappedValue"

(请注意,您将在顶级范围内添加此定义,在任何 class、结构或其他类型的定义之外)

Swift 4.0 版本从 2.0er 答案构建

/// Optional Assignment, assigns if value exists
infix operator ?=: AssignmentPrecedence

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

    guard let value = rhs else { return }
    lhs = value
}

// Playground Test

var dummy = "old"
var opt :String?

dummy ?= opt // leaves old

opt = "new"
dummy ?= opt // value becomes new