Codebase list golang-github-benbjohnson-immutable / 8e1383e
Ensure immutability of sets (and maps with SetMany) Oskar Haarklou Veileborg 1 year, 4 months ago
4 changed file(s) with 27 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
285285
286286 ## Set
287287
288 The `Set` represents a collection of unique values. It uses a `map[T]struct{}`, so it carries over some characteristics from the built-in Go `map` type.
289 Values neeed to be `comparable`.
288 The `Set` represents a collection of unique values, and it is implemented as a
289 wrapper around a `Map[T, struct{}]`.
290290
291291 Like Maps, Sets require a `Hasher` to hash keys and check for equality. There are built-in
292292 hasher implementations for most primitive types such as `int`, `uint`, and
756756 // This function will return a new map even if the updated value is the same as
757757 // the existing value because Map does not track value equality.
758758 func (m *Map[K, V]) SetMany(entries map[K]V) *Map[K, V] {
759 n := m.clone()
760759 for k, v := range entries {
761 n.set(k, v, true)
762 }
763 return n
760 m = m.Set(k, v)
761 }
762 return m
764763 }
765764
766765 func (m *Map[K, V]) set(key K, value V, mutable bool) *Map[K, V] {
16431642
16441643 // SetMany returns a map with the keys set to the new values.
16451644 func (m *SortedMap[K, V]) SetMany(entries map[K]V) *SortedMap[K, V] {
1646 n := m.clone()
16471645 for k, v := range entries {
1648 n.set(k, v, true)
1649 }
1650 return n
1646 m = m.Set(k, v)
1647 }
1648 return m
16511649 }
16521650
16531651 func (m *SortedMap[K, V]) set(key K, value V, mutable bool) *SortedMap[K, V] {
1717 m: NewMap[T, struct{}](hasher),
1818 }
1919 for _, value := range values {
20 s.m.set(value, struct{}{}, true)
20 s.m = s.m.set(value, struct{}{}, true)
2121 }
2222 return s
2323 }
2626 //
2727 // This function will return a new set even if the set already contains the value.
2828 func (s Set[T]) Set(values ...T) Set[T] {
29 n := Set[T]{
30 m: s.m.clone(),
31 }
32 for _, value := range values {
33 n.m.set(value, struct{}{}, true)
34 }
35 return n
29 for _, value := range values {
30 s.m = s.m.Set(value, struct{}{})
31 }
32 return s
3633 }
3734
3835 // Delete returns a set with the given key removed.
3936 func (s Set[T]) Delete(values ...T) Set[T] {
40 n := Set[T]{
41 m: s.m.clone(),
42 }
43 for _, value := range values {
44 n.m.delete(value, true)
45 }
46 return n
37 for _, value := range values {
38 s.m = s.m.Delete(value)
39 }
40 return s
4741 }
4842
4943 // Has returns true when the set contains the given value
136130 m: NewSortedMap[T, struct{}](comparer),
137131 }
138132 for _, value := range values {
139 s.m.set(value, struct{}{}, true)
133 s.m = s.m.set(value, struct{}{}, true)
140134 }
141135 return s
142136 }
145139 //
146140 // This function will return a new set even if the set already contains the value.
147141 func (s SortedSet[T]) Set(values ...T) SortedSet[T] {
148 n := SortedSet[T]{
149 m: s.m.clone(),
150 }
151 for _, value := range values {
152 n.m.set(value, struct{}{}, true)
153 }
154 return n
142 for _, value := range values {
143 s.m = s.m.Set(value, struct{}{})
144 }
145 return s
155146 }
156147
157148 // Delete returns a set with the given key removed.
158149 func (s SortedSet[T]) Delete(values ...T) SortedSet[T] {
159 n := SortedSet[T]{
160 m: s.m.clone(),
161 }
162 for _, value := range values {
163 n.m.delete(value, true)
164 }
165 return n
150 for _, value := range values {
151 s.m = s.m.Delete(value)
152 }
153 return s
166154 }
167155
168156 // Has returns true when the set contains the given value
66 func TestSetsPut(t *testing.T) {
77 s := NewSet[string](nil)
88 s2 := s.Set("1").Set("1")
9 s2.Set("2")
910 if s.Len() != 0 {
1011 t.Fatalf("Unexpected mutation of set")
1112 }