0

我遇到了一个难以理解的问题,但我想问问了解它的可能性。

此代码由帮助我解决另一个问题的人提供:

protocol Proto { var value: String { get } }
extension URLError: Proto { var value: String { return "hello" } }

func value(_ error: Error) {
    if let error = error as? Proto {
        print("proto", error.value)
    } else {
        print(":(")
    }
}

我除了运行时多态之外,转换应该起作用,并且proto hello在传递URLError对象时应该打印以下调用:

value(URLError(.badURL))

但这是我得到的,在 Swift 5.0 中,铸造工作,在 Swift 5.3 中,铸造不起作用。

在这里尝试 replit.com 进行个人测试和演员工作

在此处输入图像描述

swift 版本是 5.0.x,如图所示:

在此处输入图像描述

我在本地操场上测试了代码,铸造不起作用,我的快速版本是:

Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)

此外,提供代码的人在他的机器上安装了 Swift 5.4,并且铸造对他也不起作用。

希望哪位能回复一下,写的更简单,适合初学者。


更新

某人告诉我

尝试将其添加为 value() 中的第一行: print(type(of: error)) 你可能会对它打印出来的内容感到惊讶。

如果在这里有帮助,我想分享我的回复:

我确实有想过它会在两个版本中打印什么。

对于 5.0 版,它打印:

URLError
proto hello

在 5.3 版中,它打印:

NSError
:(

我有一个答案,为什么以下表达式有效:

let error = URLError(.badURL) as NSError
print(type(of: a)) // NSError

这适用于 Swift 的两个版本。

它与 swift 中的自动桥接有关,swift 中存在一系列类型,它们在 Objective-c 中具有对应的类型。NSString<-->String是另一个示例。

所以,我相信这是因为结构URLError符合Error协议,而类NSError符合Error协议,所以就像Error协议是这种转换的桥梁......我觉得它有点道理。

但是,我是一个URLError
演员,Error
在运行时被问到你实际上是什么类型
我应该回答我NSError吗?!是NSError介于两者之间吗?

Swift 5.0 确实看到了 URLError 的实际对象,但 Swift 5.3 没有。

当我将已经转换为 NSError 的对象传递给:

value(URLError(.badURL) as NSError)

然后他们俩都将其视为 NSError 然后结束:

print(type(of: error)) // NSError

我对此案感到有道理。

完成此评论后,我觉得这像是 5.0 中的错误行为并在更高版本中修复?并且一旦你构造了任何符合 Error 协议的类型,它的实际类型就从运行时检查中隐藏了?

4

0 回答 0