gpt4 book ai didi

Swift 3 类型推理混淆

转载 作者:搜寻专家 更新时间:2023-10-31 08:25:30 25 4
gpt4 key购买 nike

我正在使用 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 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 不能?

最佳答案

更新的答案 - 对于 macOS
在 Xcode 8 beta 6 中,Swift 不再隐式地将 Swift 值类型桥接到 Foundation 类类型。这意味着如果函数需要 NSNumber然后你传递了一个 Int变量,您必须将其显式转换为 NSNumber .这对于整数文字不是必需的,因为 Swift 仍然会正确推断类型。

Why does 1 compile, but 2 does not?


1 编译是因为 Swift 能够推断 20 的类型成为 NSNumber , 所以 ["a": 20]用作 [String: NSNumber] .
2 不能编译,因为 a 的类型已成立为 Int ,因此您需要将其显式转换为 NSNumber . Xcode 的修复建议 NSNumber(a) ,但遗憾的是不能编译。使用 NSNumber(value: a)a as NSNumber .

Why do 2 and 3 have different error messages?


对于 2,您提供的是字典文字 ["a": a]所以 Swift 会检查每个键和值的类型,看它是否与它期望的字典类型匹配。自 aInt并且值为 NSNumber ,您会收到错误 无法将“Int”类型的值转换为预期的字典值类型“NSNumber” .它希望您提供转换。
对于 3,您提供的是 [String, Int] 类型的变量. Swift 告诉您它无法将其转换为 [String, NSNumber] .由于 Xcode 8 beta 6 的变化,它可以,但不能没有显式转换。

Why does 4 compile, but 5 does not?


4 编译,因为您现在向 [String: NSNumber] 提供显式强制转换那3个缺少。
5 无法编译,因为您再次提供了一个字典字面量,Swift 会检查每个键和值以确保它们是正确的类型。它不会转换 IntNSNumber没有显式转换,所以这里的错误是 无法将“Int”类型的值转换为预期的字典值类型“NSNumber” .关键是当您将字典文字转换为字典类型时,Swift 不会转换它的单个键和值。您必须直接为每个 Actor 提供该类型转换。

上一个答案 - 对于 iOS
使用 Xcode 8 beta 6,参数的类型 metrics已更改为 [String: Any]? .现在,前 4 个示例可以编译,而第 5 个没有。您的前两个问题不再有效。剩下的唯一问题是:

Why does 4 compile, but 5 does not?


语句 4 ( met as [String: NSNumber] ) 编译,因为 met有类型 [String: Int]和 swift 可以转换 [String: Int][String: NSNumber] .在这种情况下,它正在查看整个字典。 Swift 知道如何转换 IntNSNumber ,但如果没有您明确要求它这样做,它就不会这样做。在本例中,由于您提供的是 [String: Int] 类型的字典。并要求它将其转换为 [String: NSNumber] ,您要求它转换 IntNSNumber .
在语句 5 中,您正在转换字典文字 ["a": a]到字典类型 as [String: NSNumber] .错误信息是:
无法将“Int”类型的值转换为预期的字典值类型“NSNumber”
在这种情况下,Swift 正在查看各个类型,检查 "a"StringaNSNumber .将字典文字转换为类型不会显式地将每个键和值转换为相应的类型。在这种情况下,您只是展示它们并说它们已经是那种类型。由于 Xcode 8 beta 6 的新变化,Swift 将不再隐式地将 Swift 值类型转换为桥接的 Foundation 类型。所以 Swift 希望你显式转换 Int aNSNumber .
有两种方法可以让 Swift 开心:
["a": NSNumber(value: a)] as [String: NSNumber]
["a": a as NSNumber] as [String: NSNumber]
当然,现在在这两种情况下,字典文字都可以推断为 [String: NSNumber]所以在不必要的 Actor 。
此外,由于 metrics现在是 [String: Any] , 转换 ["a": a] 没有意义至 [String: NSNumber][String: Int]会做。

关于Swift 3 类型推理混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39048156/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com