在这种情况下,为什么我必须明确地解开我的字符串?

时间:2015-03-14 22:24:25

标签: swift

我有一个字符串var oneString: String!,稍后在一个方法中,当我想将一个字符串连接到oneString时,我必须这样做:

oneString! += anyString

如果我没有添加!,我会收到错误'String!' is not identical to 'CGFloat'

如果我使用var oneString = ""初始化我的字符串,我就不会遇到此问题。为什么?为什么我需要打开oneString,而我明确表示在我宣布它时不会为零?

2 个答案:

答案 0 :(得分:6)

  

为什么我需要打开oneString,而我明确表示在我宣布它时不会为零?

你误解了var oneString: String!的含义。这并不意味着oneString不会是零。如果您将类型声明为var oneString: String然后,则声明的类型不能为零。

类型String!是“隐式解包的可选”。也就是说,它是一个可选项,非常类似于String?,但它假装是一个非可选的有时。主要是为了阅读它 - 你不必明确地解开它来获得价值。缺点是,如果它永远是零(并且它完全可以),您的代码将陷阱并中止。

但这种假装不可选只是到目前为止。当该参数不是可选的时,您不能将String!传递给inout的函数。因此你的问题。

Anton的回答完全正确,为什么它不起作用,他建议的运算符重载将使你的代码编译。但它不是正确的解决方案 - 您应该避免使用隐式解包的选项,因为它们是弹簧加载的死亡陷阱,并且仅在特定情况下使用(最常见的是使用Cocoa UI控件)。使用常规可选或非可选的

,在1,000个中有999次你会更好

答案 1 :(得分:3)

原因是Swift中FooFoo?Foo!不同的类型。

某些运营商已为您预先定义了#34;开箱即用的运营商"这允许FooFoo!之间具有很大的透明度,但这些类型仍然不一样。

说到字符串,运算符

func += (inout left: String!, right: String)

...根本没有定义。

如果你声明它:

func += (inout left: String!, right: String) {
    left = left + right
}

...那么你的代码应该按你喜欢的方式编译,即:

oneString! += anyString