我想简化一直需要做的事情
if let firstName = firstName {
self.name = firstName
}
执行此操作的可能的自定义通用运算符将是
infix operator ?= {}
func ?= <T>(inout left: T, right: T?) {
if let right = right {
left = right
}
}
将上一个示例简化为
self.name ?= firstName
如果 firstName 的值为 nil ,则会产生一个问题,那么Swift会将值包装在一个可选项中。
var name: String? = "Bob"
var firstName: String? = nil
self.name ?= firstName
print(self.name)
/*
prints "nil" since it is wrapping firstName in an optional when
passed in.
E.g. Optional<nil> gets unwrapped to nil in function and assigned
*/
对自定义运算符的任何可能修复?我试图将左手参数限制为不可选,但这对于通用的类型约束是不可能的。
答案 0 :(得分:11)
问题(正如您已经正确识别的那样)是因为左侧参数的类型为 If Not trange.Value Is Nothing Then
If .Cells(6, trange.Value).Value = "BOL" Then
'set first address
Set fr = .Range(trange.Address)
Do
'result counter
c = c + 1
'save each address within cache range
For Each i In addr
If i.Value = "" Then i.Value = trange.Address
Next i
Set trange = trange.FindNext(trange)
Loop While trange.Address <> fr.Address
End IF
End If
,当您将可选项传递给它时T
将被推断为{{1} }}。因为右侧参数是T
(因为类型可以自由地提升为选项),它会将类型推断为Optional<Whatever>
,从而导致您正在观察的令人困惑的双重包装。
解决方案是添加一个重载来处理左侧参数也是可选的情况。
T?
(请注意,在Swift 3中,Optional<Optional<Whatever>>
应出现在参数类型之前)
现在,如果你使用带有可选作为左手参数的this运算符,Swift将使用重载版本而不是原始版本,因为它总是支持更多类型特定的签名。这意味着右侧不会被双重选项包裹,因为它现在与左侧参数的类型完全相同。
infix operator ?= {}
func ?= <T>(inout left: T, right: T?) {
if let right = right {
left = right
}
}
// overload to deal with an optional left handed side
func ?= <T>(inout left: T?, right: T?) {
if let right = right {
left = right
}
}
请注意,这类似于inout
所做的,它有两个定义来处理一方是可选的,一方是非可选的&amp;双方都是可选的,以避免产生双重包裹的选项:
var name: String? = "Bob"
var firstName: String? = nil
name ?= firstName
print(name) // prints: Optional("Bob")
答案 1 :(得分:1)
我发现了一种通过 Nil Coalescing Operator 来减少if let
开销的有趣方法
nil合并算子(a ?? b)打开一个可选的a if 包含一个值,如果a为nil,则返回默认值b。该 表达式a始终是可选类型。表达式b必须 匹配存储在。
中的类型
总之 -
nonOptional = optional ?? someDefaultValue
例如。 -
let defaultColorName = "red"
var userDefinedColorName: String? // optional variable
var colorNameToUse = userDefinedColorName ?? defaultColorName
因此,如果userDefinedColorName
为零,那么defaultColorName
将被分配给非可选变量colorNameToUse
。
有关完整参考,请查看此Swift documentation