【发布时间】:2015-11-10 21:32:13
【问题描述】:
我无法理解为什么对泛型协议的元组进行类型别名处理突然允许我将其视为非泛型协议。由于 Swift 泛型的工作方式,我们预计示例 1、3、4 和 5 中会出现错误。但是为什么示例 2 有效?它在语义上与示例 3 有何不同?
示例 1:
正如预期的那样,这不会编译:
let foo: Hashable = "a" // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements
因为Hashable 从Equatable 继承了Self 要求。
示例 2:
但如果我定义一个 Hashable 的元组,它就可以工作!
typealias CompositeHashable = (Hashable, Hashable)
let foo: CompositeHashable = (1, "a") // This works!
现在我不再需要使用Hashable 作为通用约束。
示例 2b:
我什至可以在集合中使用CompositeHashable:
let bar: [CompositeHashable] = [(1, "a"), ("b", "a")] // This works!
示例 3:
有趣的是,如果我不对元组键入别名,它就不起作用。
let foo: (Hashable, Hashable) = (1, "a") // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements
这应该等同于示例 2,对吧?
示例 4:
此外,1-tuple 也不起作用,不管有没有 typealias:
typealias HashableTuple = (Hashable)
let foo: HashableTuple = ("a") // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements
示例 5:
还有一点。如果我从示例 2 中获取先前的 typealias CompositeHashable,并将其简单地移动到一个结构中,它现在会给出我们在其他情况下预期的相同错误。
struct CompositeKey {
typealias CompositeHashable = (Hashable, Hashable) // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements
}
谁能解释一下这里发生了什么?
【问题讨论】:
-
绝对看起来像一个错误..