我得到了这个协议和实现它的结构。
protocol TextRepresentable {
var textualDescription: String { get }
}
struct Hamster: Textrepresentable {
var name: String
var textualDescription: String {
return "A hamster named \(name)"
}
}下面的代码是如何工作的?
extension Collection where Iterator.Element: TextRepresentable {
var textualDescription: String {
let itemsAsText = self.map { $0.textualDescription }
return "[" + itemsAsText.joined(separator: ", ") + "]"
}
}扩展集合对下面的代码做了什么?
let murrayTheHamster = Hamster(name: "Murray")
let morganTheHamster = Hamster(name: "Morgan")
let mauriceTheHamster = Hamster(name: "Maurice")
let hamsters = [murrayTheHamster, morganTheHamster, mauriceTheHamster]
print(hamsters.textualDescription)发布于 2017-02-19 22:52:42
这段代码
extension Collection where Iterator.Element: TextRepresentable {
var textualDescription: String {
let itemsAsText = self.map { $0.textualDescription }
return "[" + itemsAsText.joined(separator: ", ") + "]"
}
}在Collection上创建一个仅当Collection 中的元素为 TextRepresentable时才有效的扩展(即符合协议TextRepresentable)。如果Collection是这种情况(Array是Collection),则扩展会将计算属性textualDescription添加到Collection中。
在您的示例代码中,hamsters只包含符合TextRepresentable的Hamster类型的对象。因此,编译器知道扩展对于您的Array hamsters是有效的,并且属性textualDescription是可用的。
textualDescription的实现也相当简单。
// Defines a property named textualDescription of type String
var textualDescription: String {
// Calls textualDescription on every element of the array
// and adds the return values to a new array itemsAsText
let itemsAsText = self.map { $0.textualDescription }
// Creates a string starting with "[" followed by
// all the elements in itemsAsText, separated by ",",
// and a "]". Then, returns that String
return "[" + itemsAsText.joined(separator: ", ") + "]"
}发布于 2017-02-22 21:28:40
让我们把它一块一块地拿出来。这段代码:
extension Collection where Iterator.Element: TextRepresentable {
//...
}定义符合Collection的类型的扩展,其Iterator.Element为TextRepresentable。查看文档,我们可以看到Array符合继承自Collection的MutableCollection。因此,Array间接地符合Collection。您的hamsters数组是一个元素为Hamster的Array (因此是一个Collection)。由于Hamster为TextRepresentable,因此您的hamsters阵列有资格接收此扩展。
现在让我们看看这个扩展提供了什么:
var textualDescription: String {
// ...
}这是一个名为textualDescription的计算属性,它返回一个String。此计算属性将在符合此扩展条件的所有类型上可用。深入研究它是如何工作的:
let itemsAsText = self.map { $0.textualDescription }此集合中的项使用map(_:)转换为其textualDescription的Array。在您的示例中,[Hamster(name: "Murray"), Hamster(name: "Morgan"), Hamster(name: "Maurice")]被映射到Array:["Murray", "Morgan", "Maurice"]
return "[" + itemsAsText.joined(separator: ", ") + "]"然后,所有这些文本描述都由, "连接起来,生成字符串:"Murray", "Morgan", "Maurice"
然后用[和]对其进行包装,以生成最终的结果字符串:["Murray", "Morgan", "Maurice"]
如果您有任何后续问题,请告诉我。
https://stackoverflow.com/questions/42328552
复制相似问题