Marc Knaup
09/26/2019, 7:27 AMObjects.hash(foo, bar, baz, …)
to something like this?
hash { foo x bar x baz x … }
Just the boxing is a little tricky as well as getting it to work with just a single non-Int
value without introducing boxing.
Implementation:
inline fun hash(block: HashScope.() -> Int) =
HashScope.block()
object HashScope {
inline infix fun Any?.x(hashable: Any?) =
(31 * hashCode()) + hashable.hashCode()
inline infix fun Any?.x(hashable: Int) =
(31 * hashCode()) + hashable
inline infix fun Int.x(hashable: Any?) =
(31 * this) + hashable.hashCode()
inline infix fun Int.x(hashable: Int) =
(31 * this) + hashable
}
class Example(val foo: String, val bar: List<Any>?, val baz: Int) {
override fun hashCode() =
hash { foo x bar x baz }
}
jw
09/26/2019, 12:02 PMhashOf(vararg args: Any?)
which seems more idiomatic than a somewhat-cryptic DSL? Then you can add an intrinsic in the compiler, similar to what's being explored in javac.Marc Knaup
09/26/2019, 12:04 PMObjects.hash()
cause a lot of wrapping (primitives/inline classes)? + additional array and ArrayList allocation.
Or are calls replaced by something intrinsic at runtime?jw
09/26/2019, 12:06 PMMarc Knaup
09/26/2019, 12:09 PMmarcinmoskala
10/06/2019, 6:26 PMoverride fun hashCode(): Int =
hashCodeFrom(timeZone, millis)
inline fun hashCodeFrom(vararg values: Any?) =
values.fold(0) { acc, value ->
(acc * 31) + value.hashCode()
}