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

cig3rfwq  于 2022-11-06  发布在  Swift
关注(0)|答案(3)|浏览(167)

有时我发现自己在写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,因此并不等效(如果是有意的,也是好的)。
我想我对苹果的愿望应该是

nonOptionalInt = optionalInt ??

nonOptionalInt ??= optionalInt
1cklez4t

1cklez4t1#

您正在寻找的是nil合并运算符。
在这种情况下,您可以这样使用它:

nonOptionalInt = optionalInt ?? nonOptionalInt

编辑

回复:您对您问题的最后一次编辑:
“* 我想我对苹果的愿望应该是 * 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"
  • (请注意,您会在最上层范围加入这个定义,在任何类别、结构或其他型别的定义之外)*
toe95027

toe950272#

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
wnrlj8wa

wnrlj8wa3#

在swift 2中有没有一种等价的方法,可以用一行简洁的语句来表达,而不用添加一个中间变量if let i?
如果要执行以下操作,可以省略中间值:

if optionalInt != nil {
    nonOptionalInt = optionalInt!
}

当然,如果需要,您可以将所有内容放在一行中:

if optionalInt != nil { nonOptionalInt = optionalInt! }

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

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

这里的0只是optionalInt == nil情况下使用的默认值。如果你不想把nonOptionalInt改为optionalInt == nil,那么就使用nonOptionalInt

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

请注意,optionalInt!中的!隐式地展开了可选值--这是您告诉编译器您知道optionalInt不是nil的方式,因此可以将其赋值给非可选变量。

相关问题