隐式展开的可选值真的是可选值吗?
Are implicitly unwrapped optionals truly optionals?
在 Swift 4.0 中,以下代码无法编译:
var str: String!
func someFunc(_ s: inout String?) {}
someFunc(&str)
现在我想象 str
实际上是 String?
类型,并且 Swift 编译器似乎同意:
Cannot pass immutable value of type 'String?' as inout argument
我可以通过将变量类型更改为 String?
或将函数参数更改为 (_ s: inout String!)
来解决此问题,但我不明白为什么必须这样做。 Swift 似乎已经同意 var str : String!
是 "of type 'String?'" — 那为什么不让我在这里传递它呢?
我可以使用另一个选项来隐式展开我的变量,但仍将其传递给修改可选的函数吗?
我尝试了 someFunc(&(str?))
,这只会让事情变得更奇怪 — 然后 Swift 抱怨:
Cannot pass immutable value of type 'String!' as inout argument".
所以 str
是 String?
但不能作为 String?
传递,而 str?
是 String!
?!
该代码实际上是:
var str: String!
func someFunc(_ x: inout String!) {}
someFunc(&(str?))
所以也许 Swift 在其错误消息中错误地说明了参数的类型,而不是传递的值……或者什么?
这是一个 known bug in the swift compiler. 已在 Swift 4.1 快照中修复,因此可能会在下一个 Xcode 版本 (9.3) 中修复。
您可以通过删除 implicitly-unwrapped 可选 (IUO) 来解决这个问题,无论如何都应该避免。根据它目前是 IUO 的原因,可以:
var str: String?
func someFunc(_ x: inout String?) {}
someFunc(&str)
或
var tmp: String?
func someFunc(_ x: inout String?) {}
someFunc(&tmp)
let str = tmp!
我强烈推荐第一种,除非绝对必要,否则请避免使用 force-unwrapping。
在 Swift 4.0 中,以下代码无法编译:
var str: String!
func someFunc(_ s: inout String?) {}
someFunc(&str)
现在我想象 str
实际上是 String?
类型,并且 Swift 编译器似乎同意:
Cannot pass immutable value of type 'String?' as inout argument
我可以通过将变量类型更改为 String?
或将函数参数更改为 (_ s: inout String!)
来解决此问题,但我不明白为什么必须这样做。 Swift 似乎已经同意 var str : String!
是 "of type 'String?'" — 那为什么不让我在这里传递它呢?
我可以使用另一个选项来隐式展开我的变量,但仍将其传递给修改可选的函数吗?
我尝试了 someFunc(&(str?))
,这只会让事情变得更奇怪 — 然后 Swift 抱怨:
Cannot pass immutable value of type 'String!' as inout argument".
所以 str
是 String?
但不能作为 String?
传递,而 str?
是 String!
?!
该代码实际上是:
var str: String!
func someFunc(_ x: inout String!) {}
someFunc(&(str?))
所以也许 Swift 在其错误消息中错误地说明了参数的类型,而不是传递的值……或者什么?
这是一个 known bug in the swift compiler.
您可以通过删除 implicitly-unwrapped 可选 (IUO) 来解决这个问题,无论如何都应该避免。根据它目前是 IUO 的原因,可以:
var str: String?
func someFunc(_ x: inout String?) {}
someFunc(&str)
或
var tmp: String?
func someFunc(_ x: inout String?) {}
someFunc(&tmp)
let str = tmp!
我强烈推荐第一种,除非绝对必要,否则请避免使用 force-unwrapping。