【问题标题】:Is Swift type-inference contradicting itself here?Swift 类型推断在这里自相矛盾吗?
【发布时间】:2014-08-24 21:08:30
【问题描述】:

这是我的测试代码:

var myDict: [String: AnyObject] = ["k":"v"]

var a = myDict["k"]
var b = a as String

var c = myDict["k"] as String

这是我在 Xcode6-beta6 中的 Swift Playground:

根据类型推断的规则,不抱怨c与不抱怨b逻辑矛盾吗?

【问题讨论】:

  • 复制代码并将其粘贴到问题中。如果你想展示游乐场也很好。就个人而言,我不会输入您的代码并处理可能的拼写错误以提供答案。
  • 糟糕,我没想到。完成。

标签: xcode swift xcode6 swift-playground xcode6-beta6


【解决方案1】:

我相信这是一个错误。这里发生的部分情况是String 不是一个对象。如果将第一行更改为:

var myDict: [String: Any] = ["k":"v"]

那么一切都很好。因此,鉴于字符串不是对象,将AnyObject? 类型的变量转换为String 肯定会产生错误。而且,由于编译器已经确定 a 的类型为 AnyObject?,它应该抱怨将 a 转换为 String。

请注意,如果您将最后一行更改为:

var c = myDict["k"] as NSString

错误消失了,支持问题是String 不是对象的概念。如果您将 Int 作为数组中的值并尝试将其转换为 Int,您会得到同样的抱怨。

更新:

所以情节变厚了。如果你不import Foundation 或导入一些导入 Foundation 的东西,那么你会得到额外的错误。没有基础:

很明显,这与Strings 作为非对象和NSStrings 作为对象的双重性质以及Strings 作为NSStrings 使用的能力有关,而Foundation 是进口的。

【讨论】:

  • String 确实不是一个对象,它是一个结构体:真的很不方便。
  • 啊,是的,有道理。所以bug是让无效程序运行,而不是阻止有效程序运行。
  • 但如果你有:["k":1] 将会发生崩溃。
【解决方案2】:

这与Dictionary 有两个 下标重载有关:

subscript (key: Key) -> Value?
subscript (i: DictionaryIndex<Key, Value>) -> (Key, Value) { get }

第一个是你熟悉的,你传递一个键,它给你一个可选的值;并且可以用来设置键的值。

第二个不太常见。我相信DictionaryIndex是一种进入字典的迭代器,你可以用它作为下标直接获取那个迭代器的键值对。

当编译器找不到匹配的重载时(在这种情况下,第一个不匹配,因为它返回一个可选项,不能强制转换为非可选的String),它只是任意选择一个(好吧,无论如何,这对我来说似乎是任意的)显示在错误中。在这个地方,它会选择你不认识的第二个。这就是为什么你觉得这个错误很奇怪的原因。

【讨论】:

  • 我不认为这是任意的;根据我的经验,编译器会仔细选择错误的 :)
【解决方案3】:

这行得通。

var c = myDict["k"] as AnyObject! as String   // "v"

要回答您的问题,Swift 抱怨的原因可能是您试图一次性完成这两个转换。请记住,语句var a = myDict["k"] 已经包含一个隐式转换。隐含的转换是AnyObject?,所以上面的也可以这样工作:

var c = myDict["k"] as AnyObject? as String   // "v"

请注意,如果未定义键 "k",上述内容将导致运行时错误。您可以通过转换为String? 来允许它返回nil。

【讨论】:

  • 好的,但是 Swift 语言肯定打算具有传递的类型向下转换语义。那么你同意这是一个编译器错误吗?
  • 当然 Swift 应该有很多修复来消除大量的转换。
  • 如果值不是String,则需要if let。 if let c = myDict["k"] as AnyObject! as? String
猜你喜欢
  • 2021-07-13
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 1970-01-01
相关资源
最近更新 更多