我正在阅读有关Swift协议组合的文档,发现如下:https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#:~:text=Reference%20Types.-,Protocol%20Composition,-It%20can%20be
--要求一种类型同时符合多个协议是很有用的。您可以通过协议组合将多个协议组合成一个单一需求。协议组合的行为就好像您定义了一个临时本地协议,该协议具有组合中所有协议的组合需求。协议组合不定义任何新的协议类型。
协议组合采用SomeProtocol & AnotherProtocol格式。您可以列出所需的任意多个协议,并将它们用符号(&)分隔。除了它的协议列表之外,协议组合还可以包含一个类类型,您可以使用它来指定所需的超类。
下面是一个示例,它将名为“命名”和“老化”的两个协议组合为一个函数参数的单一协议组合需求:
protocol Named {
var name: String { get }
}
protocol Aged {
var age: Int { get }
}
struct Person: Named, Aged {
var name: String
var age: Int
}
func wishHappyBirthday(to celebrator: Named & Aged) {
print("Happy birthday, \(celebrator.name), you're \(celebrator.age)!")
}
let birthdayPerson = Person(name: "Malcolm", age: 21)
wishHappyBirthday(to: birthdayPerson)
// Prints "Happy birthday, Malcolm, you're 21!"有人能解释一下,当一个类型符合两个或多个协议时,符号和逗号之间的区别吗?我在操场上测试了这个,两个符号和逗号都运行得很好。我试过在网上做一些研究,但没有找到一个很好的答案。
发布于 2022-07-07 07:12:43
您可以在类型声明中使用,,如您的struct Person: Named, Aged。
但是对于参数列表和其他上下文,,已经是一个分隔符。因此,要指定一种表示“必须同时符合协议Foo和协议条”的类型,就必须使用不同的字符。这就是为什么您需要编写func wishHappyBirthday(to celebrator: Named & Aged)。编写变量(如let anotherCelebrator: Named & Aged = … )也是如此。您也可以像这样做别名:typealias NamedAndAged = Named & Aged。
所以问题是,为什么我们在声明类型时不使用&呢?我认为答案是历史的,据我所知,在Swift 1中没有协议组合(当它被引入时找不到;Swift 4?)。结果发现,在很多情况下,您可以使用&:
struct Foo: Codable & Identifiable {
var id: UUID { UUID() }
}
class Bar: NSObject & Codable {
}它不适用于第一种和第二种类型的enum:enum Baz: Int & CaseIterable { … }会产生编译器错误,但是允许使用enum Baz: Int, CaseIterable & Identifiable { … }。
https://stackoverflow.com/questions/72893237
复制相似问题