在Swift中,为什么错误“类型别名引用自身”取决于类型别名的定义位置?

时间:2018-08-01 15:15:26

标签: swift generics swift-protocols swift-extensions

我正在Xcode 9.4.1中使用Swift 4.1。我需要创建一个字典,以将有限数量的数据类型作为值保存,因此我想将字典定义为比[String: Any]更具体的东西。我决定创建一个协议,并利用Swift 4的条件一致性来允许嵌套相同类型的字典。我的代码如下:

protocol MetricsValue {}
typealias MetricsDictionary = [String: MetricsValue]

//Now define which types can go in the dictionary:
extension String: MetricsValue {}
extension Dictionary: MetricsValue where Key == String, Value == MetricsDictionary {}

这无法编译,并显示以下错误:“类型别名MetricsDictionary自身引用。”然后,我尝试了一下,但并不是真的期望它能起作用:

protocol MetricsValue {}

//Now define which types can go in the dictionary:
extension String: FDGoogleMetricsValue {}
extension Dictionary: MetricsValue where Key == String, Value == MetricsDictionary {}

typealias MetricsDictionary = [String: MetricsValue]

它会编译!在扩展名下面定义类型别名是可行的。为什么第二个示例可以编译,但是第一个示例失败?

编辑:考虑一下之后,我实际上想使MetricsDictionary符合MetricsValue,即extension Dictionary: MetricsValue where Key == String, Value == MetricsValue的要求,但没有任何问题。我打算删除该问题,但它似乎仍然很奇怪,所以我会尽量避免其他人觉得它有用。

1 个答案:

答案 0 :(得分:1)

这很有趣,您提供的代码是

protocol MetricsValue {}
typealias MetricsDictionary = [String: MetricsValue]

extension String: MetricsValue {}
extension Dictionary: MetricsValue where Key == String, Value == MetricsDictionary {}

无法在Xcode 9.4.1中进行编译,但是在Xcode 10.0 beta(10L176w)中没有问题。另外,我已经使用Swift 4.1.2在在线swift compile中编译了代码,并且也没有问题。

Xcode 8.2.1具有相同类型的bug report,他们在8.3中进行了修复。也许它可以在当前的Xcode版本中显示出来。