我有一个字符串var oneString: String!
,稍后在一个方法中,当我想将一个字符串连接到oneString
时,我必须这样做:
oneString! += anyString
如果我没有添加!
,我会收到错误'String!' is not identical to 'CGFloat'
如果我使用var oneString = ""
初始化我的字符串,我就不会遇到此问题。为什么?为什么我需要打开oneString
,而我明确表示在我宣布它时不会为零?
答案 0 :(得分:6)
为什么我需要打开
oneString
,而我明确表示在我宣布它时不会为零?
你误解了var oneString: String!
的含义。这并不意味着oneString
不会是零。如果您将类型声明为var oneString: String
,然后,则声明的类型不能为零。
类型String!
是“隐式解包的可选”。也就是说,它是一个可选项,非常类似于String?
,但它假装是一个非可选的有时。主要是为了阅读它 - 你不必明确地解开它来获得价值。缺点是,如果它永远是零(并且它完全可以),您的代码将陷阱并中止。
但这种假装不可选只是到目前为止。当该参数不是可选的时,您不能将String!
传递给inout
的函数。因此你的问题。
Anton的回答完全正确,为什么它不起作用,他建议的运算符重载将使你的代码编译。但它不是正确的解决方案 - 您应该避免使用隐式解包的选项,因为它们是弹簧加载的死亡陷阱,并且仅在特定情况下使用(最常见的是使用Cocoa UI控件)。使用常规可选或非可选的
,在1,000个中有999次你会更好答案 1 :(得分:3)
原因是Swift中Foo
,Foo?
和Foo!
是不同的类型。
某些运营商已为您预先定义了#34;开箱即用的运营商"这允许Foo
和Foo!
之间具有很大的透明度,但这些类型仍然不一样。
说到字符串,运算符
func += (inout left: String!, right: String)
...根本没有定义。
如果你声明它:
func += (inout left: String!, right: String) {
left = left + right
}
...那么你的代码应该按你喜欢的方式编译,即:
oneString! += anyString