gpt4 book ai didi

swift - 为什么在 Swift 中对泛型协议(protocol)的元组进行类型别名允许我将其视为非泛型协议(protocol)?

转载 作者:可可西里 更新时间:2023-10-31 23:44:27 25 4
gpt4 key购买 nike

我无法理解为什么对通用协议(protocol)的元组进行类型别名突然允许我将其视为非通用协议(protocol)。由于 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 继承了 EquatableSelf 要求。

示例 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:

此外,无论有无类型别名,一元组都不起作用:

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 中获取之前的类型别名 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
}

谁能解释一下这是怎么回事?

最佳答案

typealias CompositeHashable = (Hashable, Hashable)
CompositeHashable.self

// it is OK !!!!!

let foo: CompositeHashable = (1, "a") // This works!
foo.0.dynamicType // Int.Type
foo.1.dynamicType // String.Type
foo.dynamicType // (Hashable, Hashable).Type

Any.self // protocol<>.Protocol

let bar: [CompositeHashable] = [(1, "a"), ("b", "a")]
bar.dynamicType // Array<(Hashable, Hashable)>.Type Hashable.self // error: protocol 'Hashable' can only be used as a generic constraint because it has Self or associated type requirements

....这个很有趣

let foo: HashableTuple = ("a")

Void is a typealias for the empty tuple type, (). If there is only one element inside the parentheses, the type is simply the type of that element. For example, the type of (Int) is Int, not (Int). As a result, you can name a tuple element only when the tuple type has two or more elements.

这相当于你的类型别名

let (a,b) = ("a",1)
typealias Htuple = (A:Hashable,B:Hashable)
let t:Htuple = (a,b)

关于swift - 为什么在 Swift 中对泛型协议(protocol)的元组进行类型别名允许我将其视为非泛型协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33640000/

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