2017-02-19 53 views
0

我得到這個協議和實現它的結構。這個例子中的「擴展集合Iterator.Element:Textrepresentable」是什麼?

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) 
+1

順便說一句,Swift標準庫已經有協議來模擬這個功能('CustomStringConvertible'和'CustomDebugStringConvertible') – Alexander

+0

@Alexander我不知道這個我親愛的,我只是想了解事情是如何工作的迅速,下面的答案已經結束了我的困惑。 :) –

回答

1

此代碼

extension Collection where Iterator.Element: TextRepresentable { 
    var textualDescription: String { 
     let itemsAsText = self.map { $0.textualDescription } 
     return "[" + itemsAsText.joined(separator: ", ") + "]" 
    } 
} 

上創建Collection的擴展,它是唯一有效時在Collection的元素是TextRepresentable(即符合協議TextRepresentable)。 如果這是CollectionArrayCollection)的情況,則擴展將計算的屬性textualDescription添加到Collection

在您的示例代碼中,hamsters僅包含符合TextRepresentableHamster類型的對象。因此,編譯器知道該擴展對您的Arrayhamsters有效,並且該屬性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: ", ") + "]" 
} 
+0

非常感謝您的回答。我明白了,非常感謝你的時間。我正在快速學習,並且可以有更多的問題向你問。請在那裏回答我:)非常感謝你。 –

0

讓我們一件一件。此代碼:

extension Collection where Iterator.Element: TextRepresentable { 
    //... 
} 

定義的擴展,符合Collection類型,其Iterator.ElementTextRepresentable。查看文檔,我們看到Array符合MutableCollection,它繼承自Collection。因此,Array間接符合Collection。您的 hamsters數組是Array(因此爲Collection),其元素爲Hamster。由於HamsterTextRepresentable,因此您的hamsters陣列有資格接收此擴展。

現在讓我們來看看這個擴展給了我們:

var textualDescription: String { 
    // ... 
} 

這就是所謂textualDescription一個計算的屬性,它返回一個String。此計算出的屬性在適用於此擴展的所有類型上都可用。更深入地研究它是如何工作的:

let itemsAsText = self.map { $0.textualDescription } 

該集合的項目,採用map(_:)轉化爲他們的textualDescription S的Array。在你的榜樣,[Hamster(name: "Murray"), Hamster(name: "Morgan"), Hamster(name: "Maurice")]映射到Array["Murray", "Morgan", "Maurice"]

return "[" + itemsAsText.joined(separator: ", ") + "]" 

然後,所有的文本描述由, "連接以產生字符串:"Murray", "Morgan", "Maurice"

然後與[包裹和]產生最終生成字符串:["Murray", "Morgan", "Maurice"]

讓我知道你是否有任何後續問題。