HashableByKeyPath
帮助避免在实现 Hashable
和 Equatable
一致性时常见的错误。
lhs.foo == lhs.foo
lhs.foo1 == rhs.foo2
==
和 hash(into:)
函数中检查不同的属性;“两个相等的实例必须以相同的顺序将相同的值提供给 hash(into:)
中的 Hasher
”struct Foo: HashableKeyPathProvider {
@HashableKeyPathCollectionBuilder<TestObject>
static var hashableKeyPaths: HashableKeyPathCollection<Foo> {
\Foo.bar1
\Foo.bar2
\Foo.bar3
}
var bar1: String
var bar2: String
var bar3: Int
}
let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
let foos: Set = [foo1, foo2]
foo1 == foo1 // true
foo1 == foo2 // true
foo1 == foo3 // false
foo2 == foo3 // false
foos.count // 1
foos.contains(foo2) // true
foos.contains(foo3) // false
如果类型只需要符合 Equatable
协议,则该类型可以符合 EquatableByKeyPath
协议。
struct Foo: EquatableKeyPathProvider {
@EquatableKeyPathCollectionBuilder<TestObject>
static var equatableKeyPaths: EquatableKeyPathCollection<Foo> {
\Foo.bar1
\Foo.bar2
\Foo.bar3
}
var bar1: String
var bar2: String
var bar3: Int
}
let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
foo1 == foo1 // true
foo1 == foo2 // true
foo1 == foo3 // false
foo2 == foo3 // false
当使用非 final 类时,HashableKeyPathProvider
和 EquatableKeyPathProvider
协议不能被使用。 在这种情况下,应该使用 HashableByKeyPath
和 EquatableByKeyPath
协议。
struct Foo: HashableByKeyPath {
static func addHashableKeyPaths<Consumer: HashableKeyPathConsumer>(to consumer: inout Consumer) where Consumer.Root == Self {
consumer.addHashableKeyPath(\.bar1)
consumer.addHashableKeyPath(\.bar2)
consumer.addHashableKeyPath(\.bar3)
}
var bar1: String
var bar2: String
var bar3: Int
}
let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
let foos: Set = [foo1, foo2]
foo1 == foo1 // true
foo1 == foo2 // true
foo1 == foo3 // false
foo2 == foo3 // false
foos.count // 1
foos.contains(foo2) // true
foos.contains(foo3) // false
如果类型只需要符合 Equatable
协议,则该类型可以符合 EquatableByKeyPath
协议。
struct Foo: EquatableByKeyPath {
static func addHashableKeyPaths<Consumer: HashableKeyPathConsumer>(to consumer: inout Consumer) where Consumer.Root == Self {
consumer.addEquatableKeyPath(\.bar1)
consumer.addEquatableKeyPath(\.bar2)
consumer.addEquatableKeyPath(\.bar3)
}
var bar1: String
var bar2: String
var bar3: Int
}
let foo1 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo2 = Foo(bar: "value", bar2: "value2", bar3: "value3")
let foo3 = Foo(bar: "value2", bar2: "value2", bar3: "value3")
foo1 == foo1 // true
foo1 == foo2 // true
foo1 == foo3 // false
foo2 == foo3 // false
HashableByKeyPath
支持通过 SwiftPM 进行安装。 这可以通过将软件包添加到依赖项部分并作为目标的依赖项来完成。
let package = Package(
...
dependencies: [
.package(url: "https://github.com/JosephDuffy/HashableByKeyPath.git", from: "1.0.0"),
],
targets: [
.target(name: "MyApp", dependencies: ["HashableByKeyPath"]),
],
...
)
HashableByKeyPath
具有完整的文档,并提供在线的代码级文档。 在线文档是每次发布时从源代码生成的,因此它是最新的发布版本,但可能与 master
中的代码不同。
HashableByKeyPath
具有完整的测试套件,该套件在 GitHub actions 上作为 pull 请求的一部分运行。 所有测试必须通过才能合并 pull 请求。
代码覆盖率被收集并报告给 Codecov。
该项目以 MIT 许可证发布。 有关完整的许可,请查看 LICENSE 文件。