有时候我发现自己写了这样的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 if i?
修改
在考虑了第一个答案之后......显然有一种等效的方法
if optionalInt != nil {
nonOptionalInt = optionalInt!
}
三元运营商? :不是等价的,因为它们可能会触发原始代码没有的didSet(如果这是预期的副作用,那就很好)
到目前为止,最优雅的答案似乎是
nonOptionalInt = optionalInt ?? nonOptionalInt
它也可能触发像三元运算符这样的didSet,因此不等效(如果是这样的话也很好)。
我认为我对Apple的愿望就像是
nonOptionalInt = optionalInt ??
或
nonOptionalInt ??= optionalInt
答案 0 :(得分:10)
您要找的是nil coalescing operator。
在这种情况下你会像这样使用它:
nonOptionalInt = optionalInt ?? nonOptionalInt
修改强>
re:您对问题的最后修改:
" 我认为我对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"
(请注意,您将在顶级范围内添加此定义,超出任何类,结构或其他类型的定义)
答案 1 :(得分:3)
从2.0er awnser
构建Swift 4.0版本/// 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