為何\.self能在ForEach中使用?
轉(zhuǎn)載、翻譯自HackingWithSwift,點(diǎn)擊查看原文。
當(dāng)一個(gè)對(duì)象遵從于Identifiable時(shí),SwiftUI會(huì)自動(dòng)使用它的id來進(jìn)行“唯一化“(可以理解為一種“ForEach”一樣的遍歷);但是當(dāng)我們沒讓對(duì)象遵從于Identifiable時(shí),我們也可以用一個(gè)我們知道是唯一的的key path進(jìn)行排序(如書籍的ISBN號(hào));當(dāng)所有值都不一定是唯一的時(shí),我們就會(huì)使用\.self。
\ .在Swift中被稱為“關(guān)鍵路徑”(key path),可以用于在另一個(gè)對(duì)象上指定VAR。
首先,\.self可以用來遍歷一些簡(jiǎn)單的結(jié)構(gòu):
List {
ForEach([2, 4, 6, 8, 10], id: \.self) {
Text("\($0) is even")
}
}
這其中的原理是:當(dāng)我們把\.self作為一個(gè)標(biāo)識(shí)符(identifier)——一個(gè)struct就是一個(gè)struct,它其中只存著內(nèi)容,并沒有一個(gè)識(shí)別碼一樣的identification information,所以\.self其實(shí)給struct中的每一組值都設(shè)立了一個(gè)哈希值,并用這個(gè)獨(dú)一無二的哈希值進(jìn)行識(shí)別以及遍歷(ForEach)。
有很多構(gòu)造哈希值的方法,但所有方法都遵循哈希值的兩條原則:
- 不管輸入的數(shù)據(jù)大小如何,輸出的數(shù)據(jù)大小應(yīng)該一致。
- 輸入同一個(gè)數(shù)據(jù)必定得到同一個(gè)輸出值。
事實(shí)上,Xcode為我們的對(duì)象生成了一個(gè)遵從Hashable的class,Hashable是一個(gè)protocol,表示Swift可以為之生成哈希值。
這也是為什么Int和String都可以使用\.self——這兩個(gè)玩意兒本來就遵從Hashable。只要一個(gè)struct中的所有變量類型都遵循Hashable,這個(gè)變量類型也支持Hashable。
需要注意的是,盡管運(yùn)行一個(gè)數(shù)據(jù)兩次所輸出的哈希值理應(yīng)相同,但如果我們運(yùn)行一次、關(guān)閉程序再運(yùn)行一次,仍然可能會(huì)得到不同的哈希值。