mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
hashes: support object default hash (#17175)
This commit is contained in:
@@ -173,14 +173,16 @@ provided by the operating system.
|
||||
dumping (on select signals) and notifying the parent process about the cause
|
||||
of termination.
|
||||
|
||||
- Added `strip` and `setSlice` to `std/strbasics`.
|
||||
- `hashes.hash` now supports `object`, but can be overloaded.
|
||||
|
||||
- Added `strip` and `setSlice` to `std/strbasics`.
|
||||
|
||||
- Added to `wrapnils` an option-like API via `??.`, `isSome`, `get`.
|
||||
|
||||
- `std/options` changed `$some(3)` to `"some(3)"` instead of `"Some(3)"`
|
||||
and `$none(int)` to `"none(int)"` instead of `"None[int]"`.
|
||||
|
||||
|
||||
## Language changes
|
||||
|
||||
- `nimscript` now handles `except Exception as e`.
|
||||
|
||||
@@ -54,20 +54,6 @@ runnableExamples:
|
||||
## **Note:** If the type has a `==` operator, the following must hold:
|
||||
## If two values compare equal, their hashes must also be equal.
|
||||
##
|
||||
## You can hash an object by all of its fields with the `fields` iterator:
|
||||
runnableExamples:
|
||||
proc hash(x: object): Hash =
|
||||
for f in fields(x):
|
||||
result = result !& hash(f)
|
||||
result = !$result
|
||||
|
||||
type
|
||||
Obj = object
|
||||
x: int
|
||||
y: string
|
||||
|
||||
doAssert hash(Obj(x: 520, y: "Nim")) != hash(Obj(x: 520, y: "Nim2"))
|
||||
|
||||
## See also
|
||||
## ========
|
||||
## * `md5 module <md5.html>`_ for the MD5 checksum algorithm
|
||||
@@ -499,14 +485,24 @@ proc hashIgnoreCase*(sBuf: string, sPos, ePos: int): Hash =
|
||||
result = !$h
|
||||
|
||||
|
||||
proc hash*[T: tuple](x: T): Hash =
|
||||
## Efficient hashing of tuples.
|
||||
proc hash*[T: tuple | object](x: T): Hash =
|
||||
## Efficient hashing of tuples and objects.
|
||||
## There must be a `hash` proc defined for each of the field types.
|
||||
runnableExamples:
|
||||
type Obj = object
|
||||
x: int
|
||||
y: string
|
||||
type Obj2[T] = object
|
||||
x: int
|
||||
y: string
|
||||
assert hash(Obj(x: 520, y: "Nim")) != hash(Obj(x: 520, y: "Nim2"))
|
||||
# you can define custom hashes for objects (even if they're generic):
|
||||
proc hash(a: Obj2): Hash = hash((a.x))
|
||||
assert hash(Obj2[float](x: 520, y: "Nim")) == hash(Obj2[float](x: 520, y: "Nim2"))
|
||||
for f in fields(x):
|
||||
result = result !& hash(f)
|
||||
result = !$result
|
||||
|
||||
|
||||
proc hash*[A](x: openArray[A]): Hash =
|
||||
## Efficient hashing of arrays and sequences.
|
||||
## There must be a `hash` proc defined for the element type `A`.
|
||||
|
||||
@@ -130,5 +130,51 @@ proc main() =
|
||||
# run at CT, expecting c semantics.
|
||||
discard
|
||||
|
||||
block: # hash(object)
|
||||
type
|
||||
Obj = object
|
||||
x: int
|
||||
y: string
|
||||
Obj2[T] = object
|
||||
x: int
|
||||
y: string
|
||||
Obj3 = object
|
||||
x: int
|
||||
y: string
|
||||
Obj4 = object
|
||||
case t: bool
|
||||
of false:
|
||||
x: int
|
||||
of true:
|
||||
y: int
|
||||
z: int
|
||||
Obj5 = object
|
||||
case t: bool
|
||||
of false:
|
||||
x: int
|
||||
of true:
|
||||
y: int
|
||||
z: int
|
||||
|
||||
proc hash(a: Obj2): Hash = hash(a.x)
|
||||
proc hash(a: Obj3): Hash = hash((a.x,))
|
||||
proc hash(a: Obj5): Hash =
|
||||
case a.t
|
||||
of false: hash(a.x)
|
||||
of true: hash(a.y)
|
||||
|
||||
doAssert hash(Obj(x: 520, y: "Nim")) != hash(Obj(x: 520, y: "Nim2"))
|
||||
doAssert hash(Obj2[float](x: 520, y: "Nim")) == hash(Obj2[float](x: 520, y: "Nim2"))
|
||||
doAssert hash(Obj2[float](x: 520, y: "Nim")) != hash(Obj2[float](x: 521, y: "Nim2"))
|
||||
doAssert hash(Obj3(x: 520, y: "Nim")) == hash(Obj3(x: 520, y: "Nim2"))
|
||||
|
||||
doAssert hash(Obj4(t: false, x: 1)) == hash(Obj4(t: false, x: 1))
|
||||
doAssert hash(Obj4(t: false, x: 1)) != hash(Obj4(t: false, x: 2))
|
||||
doAssert hash(Obj4(t: false, x: 1)) != hash(Obj4(t: true, y: 1))
|
||||
|
||||
doAssert hash(Obj5(t: false, x: 1)) != hash(Obj5(t: false, x: 2))
|
||||
doAssert hash(Obj5(t: false, x: 1)) == hash(Obj5(t: true, y: 1))
|
||||
doAssert hash(Obj5(t: false, x: 1)) != hash(Obj5(t: true, y: 2))
|
||||
|
||||
static: main()
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user