Swift 3型推理混淆
我在用macOS 我有以下代码。1、2、3、4和5之间的唯一区别是“metrics”参数中的内容Swift 3型推理混淆,swift,macos,swift3,Swift,Macos,Swift3,我在用macOS 我有以下代码。1、2、3、4和5之间的唯一区别是“metrics”参数中的内容 let a = 20 let met = ["a": a] // 1: This compiles. _ = NSLayoutConstraint.constraints(withVisualFormat: "|[v1(a)]|", metrics: ["a": 20], views: ["v1": v1]) // 2: This fails with "Cannot convert value
let a = 20
let met = ["a": a]
// 1: This compiles.
_ = NSLayoutConstraint.constraints(withVisualFormat: "|[v1(a)]|", metrics: ["a": 20], views: ["v1": v1])
// 2: This fails with "Cannot convert value of type 'Int' to expected dictionary value type 'NSNumber'".
_ = NSLayoutConstraint.constraints(withVisualFormat: "|[v1(a)]|", metrics: ["a": a], views: ["v1": v1])
// 3: This fails with "Cannot convert value of type '[String: Int]' to expected argument type '[String: NSNumber]?'".
_ = NSLayoutConstraint.constraints(withVisualFormat: "|[v1(a)]|", metrics: met, views: ["v1": v1])
// 4: This compiles.
_ = NSLayoutConstraint.constraints(withVisualFormat: "|[v1(a)]|", metrics: met as [String: NSNumber]?, views: ["v1": v1])
// 5: This fails with "Cannot convert value of type 'Int' to expected dictionary value type 'NSNumber'".
_ = NSLayoutConstraint.constraints(withVisualFormat: "|[v1(a)]|", metrics: ["a": a] as [String: NSNumber]?, views: ["v1": v1])
为什么1编译,而2不编译
为什么2和3有不同的错误消息
<>为什么4编译,但5不? SWIFT 3去除了SWIFT和基础类型之间的隐式铸造(<代码> int <代码> > >代码> nStuts<代码>。code>let a=20给出
a
类型Int
,您需要使用a作为NSNumber
手动将其转换为NSNumber
。另一方面,您的第一行编译是因为20
推断出预期的NSNumber
类型
或者,您可以为a
指定NSNumber
类型以开始使用
let a: NSNumber = 20
之后,您可以在需要NSNumber
的地方使用它
我不知道为什么你的第五行没有编译-这可能是一个bug。更新的答案-适用于macOS
使用XCODE 8 beta 6,SWIFT不再隐式将SWIFT值类型桥接到基础类类型。这意味着如果一个函数需要一个
NSNumber
,并且您向它传递了一个Int
变量,那么您必须显式地将它强制转换为NSNumber
。对于整型文字而言,这不是必需的,因为Swift仍将正确推断类型
为什么1编译,而2不编译
1之所以编译,是因为Swift能够推断20
的类型为NSNumber
,因此[“a”:20]
作为[字符串:NSNumber]
工作
2不编译,因为a
的类型已被确定为Int
,因此需要将其显式转换为NSNumber
。Xcode的修复建议使用NSNumber(a)
,但遗憾的是,它无法编译。使用NSNumber(值:a)
或a作为NSNumber
为什么2和3有不同的错误消息
对于2,您提供了一个字典文本[“a”:a]
,因此Swift检查每个键和值的类型,看看它是否与它期望的字典类型匹配。由于a
是Int
且值是NSNumber
,因此出现错误无法将“Int”类型的值转换为预期的字典值类型“NSNumber”。它希望您提供转换
对于3,您提供的变量类型为[String,Int]
。Swift告诉您,它无法将其转换为[String,NSNumber]
。它可以,但由于Xcode 8 beta 6中的更改,没有显式强制转换是不行的
为什么4编译,而5不编译
4编译,因为您现在提供了3所缺少的对[String:NSNumber]
的显式转换
5不会编译,因为您再次提供了字典文本,Swift检查每个键和值以确保它们是正确的类型。在没有显式转换的情况下,它不会将Int
转换为NSNumber
,因此这里的错误是无法将“Int”类型的值转换为预期的字典值类型“NSNumber”。关键是,当您将字典文本转换为字典类型时,Swift不会转换字典文本的单个键和值。你必须为每一个直接提供该类型
先前的答案-适用于iOS 对于Xcode 8 beta 6,参数的类型
metrics
已更改为[String:Any]?
。现在,前4个示例已编译,第5个示例未编译。你的前两个问题不再有效。剩下的唯一问题是:
为什么4编译,而5不编译
语句4(met作为[String:NSNumber]
进行编译,因为met
具有类型[String:Int]
,Swift可以将[String:Int]
转换为[String:NSNumber]
。在本例中,它将字典视为一个整体。Swift知道如何将Int
转换为NSNumber
,但如果您不明确要求它这样做,它就不会这样做。在本例中,由于您正在呈现类型为[String:Int]
的字典,并要求它将其转换为[String:NSNumber]
,因此您要求它将Int
转换为NSNumber
在语句5中,您正在将字典文本[“a”:a]
强制转换为字典类型,即[String:NSNumber]
。错误消息是:
无法将“Int”类型的值转换为预期的字典值类型“NSNumber”
在这种情况下,Swift正在查看各个类型,检查“a”
是否为字符串
,a
是否为NSNumber
。将字典文本强制转换为类型不会显式地将每个键和值强制转换为相应的类型。在这种情况下,你只是介绍他们,并说他们已经是那种类型。由于XCODE 8 beta 6的新变化,SWIFT将不再隐式地将SWIFT值类型转换为桥接基础类型。因此,Swift希望您显式地将Int
a
转换为NSNumber
有两种方法可以让斯威夫特快乐:
["a": NSNumber(value: a)] as [String: NSNumber]
["a": a as NSNumber] as [String: NSNumber]
当然,现在在这两种情况下,字典文本都可以推断为[String:NSNumber]
,因此不需要强制转换
另外,由于
度量标准
现在是[String:Any]
,当[String:Int]
可以时,将[a:a]
转换为[String:NSNumber]
是没有意义的。我使用的是Xcode8b6。度量参数的类型为“[String:NSNumber]”。这些错误消息来自Xcode 8b6,因此所有问题都是有效的。您是否在macOS上开发?似乎iOS和macOS是不同的。是的,我应该提到这一点。我在macOS上。我不知道iOS和macOS是不同的。我想我还是很困惑。为什么我们之间的行为有差异