Swift 3.0字符串连接会留下“Optional”

7

从Swift 3.0开始,我在字符串方面遇到了一些麻烦,特别是在拼接方面。第一个例子是我自从开始使用Swift定义我的URL字符串以来一直在使用的方法。

internal let host: String! = "https://host.io/"
let urlString = "\(host)oauth/access_token"

其中主机被定义为在类的开头。这在Swift 3.0之前完美运行,但现在打印输出如下:

Optional("https://host.io/")oauth/access_token

这很奇怪。现在我必须写这个。

let urlString = host + "oauth/access_token"

为了获得预期的输出。
https://host.io/oauth/access_token

还有一个问题,我想与字符串相关。我再次连接字符串,但这次我使用的是+,就像与urlString一样 - 但这次不起作用。代码行看起来像这样:

self.labelName.text = currentUser.name + " " + String(describing: ageComponents.year)

很不幸,代码生成的字符串是这样的:"My Name Optional(26)"。在这种情况下,我没有解决方案。 String(describing: ageComponents.year) 不是可选类型,因此无法进行类似于 String(describing: ageComponents.year) ?? "whatever" 的操作。
有人遇到过类似的问题吗?

4
请查看Swift 3 incorrect string interpolation with implicitly unwrapped strings - 如果Swift可以将隐式解包的可选项作为强制可选项进行类型检查,则它会优先考虑这样做,而不是强制解包。在您的第二个示例中,ageComponents.year是否是(隐式解包的)可选项? - Hamish
我真的在努力看到所有这些Swift 3.0的变化中的好处,但进展非常缓慢和困难。在第二个例子中,“.year”没有被解包。这解决了第二个例子的问题。也许你应该把它写成一个答案。 - jovanjovanovic
1
我真的无法理解这个SE-0054提案。例如,如果我们做这样的事情: let x: Int! = 5 let y = x let z = x + 0; 'y'将是'Int?' - 可选的。好吧,'z'不会因为它不能被创建为可选项,因为有'+'号。我无法理解的是,为什么'y变成了Int?'从隐式解包的'Int!'创建的东西为什么会变成'Int?'?我理解'!'的意思是 - 我已经告诉你它不是可选的,所以要这样使用它。 - jovanjovanovic
1
成为强制可选项的一个很好的原因是它限制了编译器隐式强制解包的位置,这可能是崩溃的源头。与 Swift 3 的许多演进提案一样,它并不被认为是“完美模型”,而是达到该模型的一个阶段性过渡。在这种情况下,Swift 团队正在寻求彻底从语言中删除隐式解包的可选项,一旦有其他语言特性来替换它们(您可以在提案的“动机”部分阅读其理由)。 - Hamish
以下是动机的摘录:“我们希望限制它们的使用,并引入更具体的语言特性来取代它们。除了一些特定的场景外,可选项始终是更安全的选择,我们希望鼓励人们使用它们而不是IUOs。该提案旨在将IUOs的采用限制在实际需要它们的地方,并使Swift语言在其他技术使其不再必要时完全删除隐式解包可选项。” - Hamish
@Hamish,感谢你的解释。但是,这个更改对我来说似乎是在干扰程序员,试图修复和保护他们免受自己的影响 - 这也许是好语言应该做的事情。不管怎样,我不会支持这个变化,只因为它试图“代替我思考”。再次感谢您的意见。 - jovanjovanovic
1个回答

2

在Swift 3中,本机结构体DateComponents的所有属性都是可选的,与Foundation NSDateComponents对应物不同。

var year: Int? { get set }

您需要将其拆包。如果您在 ageComponents 中指定了单位 ,那么您可以安全地这样做。


1
是的,这有点反向。你必须指定你想要的单位,但它们仍然是可选的。 - Tim Vermeulen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接