Ger*_*tan 3 optional-variables swift2
有时我发现自己编写了swift 2代码,如下所示:
class Test {
var optionalInt: Int?
var nonOptionalInt: Int = 0
func test() {
if let i = optionalInt {
nonOptionalInt = i
}
// do more stuff
}
}
Run Code Online (Sandbox Code Playgroud)
有问题的部分是这样的:
if let i = optionalInt {
nonOptionalInt = i
}
Run Code Online (Sandbox Code Playgroud)
在单词中:如果optionalInt有值,则将其分配给变量nonOptionalInt,否则不执行任何操作.
在swift 2中是否有一个等效的方式来表达这个优雅的单行而不添加一个中间变量if if i?
编辑
在考虑了第一个答案之后......
显然有一种等效的方式
if optionalInt != nil {
nonOptionalInt = optionalInt!
}
Run Code Online (Sandbox Code Playgroud)
三元运营商?:不是等价的,因为它们可能会触发原始代码没有的didSet(如果这是预期的副作用,那就好了)
到目前为止,最优雅的答案似乎是
nonOptionalInt = optionalInt ?? nonOptionalInt
Run Code Online (Sandbox Code Playgroud)
它也可能像三元运算符一样触发didSet,因此不等效(如果是这样的话也很好).
我想我对Apple的愿望就像是
nonOptionalInt = optionalInt ??
Run Code Online (Sandbox Code Playgroud)
要么
nonOptionalInt ??= optionalInt
Run Code Online (Sandbox Code Playgroud)
fqd*_*qdn 10
您正在寻找的是零合并运算符.
在这种情况下你会像这样使用它:
nonOptionalInt = optionalInt ?? nonOptionalInt
Run Code Online (Sandbox Code Playgroud)
编辑
re:你对问题的最后修改:
" 我认为我对Apple的愿望会像 nonOptionalInt ??= optionalInt "
...为什么希望什么时候可以建造它?:)
我没有考虑到足以决定我是否会在一般情况下推荐这样的东西,但如果它对你的情况有帮助,你可以创建一个??=运算符,按照你的要求做这样的事情:
infix operator ??= {}
func ??= <T>(inout lhs: T, rhs: T?) -> Void {
guard let value = rhs else { return }
lhs = value
}
Run Code Online (Sandbox Code Playgroud)
然后,看看它在行动:
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"
Run Code Online (Sandbox Code Playgroud)
(请注意,您将在顶级作用域中添加此定义,在任何类,结构或其他类型的定义之外)
基于2.0er答案的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
Run Code Online (Sandbox Code Playgroud)