为何\.self
能在ForEach中使用?
转载、翻译自HackingWithSwift,点击查看原文。
当一个对象遵从于Identifiable
时,SwiftUI会自动使用它的id
来进行“唯一化“(可以理解为一种“ForEach”一样的遍历);但是当我们没让对象遵从于Identifiable
时,我们也可以用一个我们知道是唯一的的key path进行排序(如书籍的ISBN号);当所有值都不一定是唯一的时,我们就会使用\.self
。
\ .
在Swift中被称为“关键路径”(key path),可以用于在另一个对象上指定VAR。
首先,\.self
可以用来遍历一些简单的结构:
List {
ForEach([2, 4, 6, 8, 10], id: \.self) {
Text("\($0) is even")
}
}
这其中的原理是:当我们把\.self
作为一个标识符(identifier)——一个struct就是一个struct,它其中只存着内容,并没有一个识别码一样的identification information
,所以\.self
其实给struct中的每一组值都设立了一个哈希值,并用这个独一无二的哈希值进行识别以及遍历(ForEach)。
有很多构造哈希值的方法,但所有方法都遵循哈希值的两条原则:
- 不管输入的数据大小如何,输出的数据大小应该一致。
- 输入同一个数据必定得到同一个输出值。
事实上,Xcode为我们的对象生成了一个遵从Hashable
的class,Hashable
是一个protocol,表示Swift可以为之生成哈希值。
这也是为什么Int和String都可以使用\.self
——这两个玩意儿本来就遵从Hashable。只要一个struct中的所有变量类型都遵循Hashable,这个变量类型也支持Hashable。
需要注意的是,尽管运行一个数据两次所输出的哈希值理应相同,但如果我们运行一次、关闭程序再运行一次,仍然可能会得到不同的哈希值。