(2022) Generics, Reflection, and Efficient Collections (GoLab Edition)
(2022) Generics, Reflection, and Efficient Collections (GoLab Edition)
Generics,
Reflection,
15/09/2022
and
Efficient Collections
Eleanor McHugh
ELEANOR MCHUGH
GENERICS, REFLECTION,
AND EFFICIENT COLLECTIONS
PORTRAIT OF A HACKER...
PORTRAIT OF A HACKER...
/G o Note b o o k
▸ physics leanp u b : /
▸ cryptography
g ithub://feye
an o r
▸ embedded systems
eye le
▸ dynamic languages
e : //f
leanor
▸ dns provisioning
sli deshar
▸ network scaling
GoGenericsTalk
PREDEFINED COLLECTION TYPES IN GO
ARRAYS
001_array.go 002_array.go
a = [3]int{3, 2, 1}
fmt.Printf("a: %v (%T)\n", a, a)
a[0] = a[1]
for i, v := range a {
fmt.Printf("a[%v]: %v\n", i, v)
}
}
go run 001_array.go
len(a): 3
cap(a): 3
a: [0 0 0] ([3]int)
a[1]: 0 (int)
a[0:1]: [0] ([]int)
a: [3 2 1] ([3]int)
a[0]: 2
a[1]: 2
a[2]: 1
SLICES
003_slice.go 004_slice.go
package main
import "fmt"
func main() {
var c chan int
for n := range c {
fmt.Println("n:", n)
}
fmt.Println("n:", <-c)
}
go run 012_channel.go
sending: 0
sending: 2
sending: 4
sending: 6
n: 0
n: 2
n: 4
n: 6
n: 0
CHANNELS
013_channel.go
for n := range c {
fmt.Println("n:", n)
}
n, open := <-c
fmt.Printf("n: %v, open: %v\n", n, open)
}
CHANNELS
014_channel.go
Receiver:
for {
select {
case n, ok := <-c:
if ok {
fmt.Printf("len(c): %v, n: %v\n", len(c), n)
}
case <-done:
break Receiver
}
}
}
CHANNELS
015_channel.go
package main
import "fmt"
func main() {
s := ISlice{0, 1, 2, 3, 4}
fmt.Printf("%v.Sum() = %v\n", s, s.Sum())
}
go run 014_udt.go
[0 1 2 3 4].Sum() = 10
USER-DEFINED COLLECTIONS
017_udt.go
func main() {
i := Summable[int]{0, 1, 2, 3, 4}
fmt.Printf("(%T)%v.Sum() = %v\n", i, i, i.Sum())
i = ISlice{0, 1, 2, 3, 4}
fmt.Printf("(%T)%v.Sum() = %v\n", i, i, i.Sum())
f := Summable[float32]{0, 1, 2, 3, 4}
fmt.Printf("(%T)%v.Sum() = %v\n", f, f, f.Sum())
f = FSlice{0, 1, 2, 3, 4}
fmt.Printf("(%T)%v.Sum() = %v\n", f, f, f.Sum())
}
USER-DEFINED COLLECTIONS
019_generic_func.go
func main() {
i := []int{0, 1, 2, 3, 4}
fmt.Printf("Sum(%T%v) = %v\n", i, i, Sum(i))
f := []float32{0, 1, 2, 3, 4}
fmt.Printf("Sum(%T%v) = %v\n", f, f, Sum(i))
r := Sum(f).(float32)
fmt.Println("r =", r)
}
USER-DEFINED COLLECTIONS
020_generic_func.go
func main() {
i := []int{0, 1, 2, 3, 4}
fmt.Printf("Sum[%T](%v) = %v\n", i[0], i, Sum[int](i))
f := []float32{0, 1, 2, 3, 4}
fmt.Printf("Sum[%T](%v) = %v\n", f[0], f, Sum[float32](f))
is := ISlice{0, 1, 2, 3, 4}
fmt.Printf("Sum[%T](%v) = %v\n", is[0], is, Sum[int](is))
fs := FSlice{0, 1, 2, 3, 4}
fmt.Printf("Sum[%T](%v) = %v\n", fs[0], fs, Sum[float32](fs))
}
USER-DEFINED COLLECTIONS
023_generic_func.go
func main() {
i := []int{0, 1, 2, 3, 4}
fmt.Printf("Sum[%T](%v) = %v\n", i[0], i, Sum(i))
f := []float32{0, 1, 2, 3, 4}
fmt.Printf("Sum[%T](%v) = %v\n", f[0], f, Sum(f))
is := ISlice{0, 1, 2, 3, 4}
fmt.Printf("Sum[%T](%v) = %v\n", is[0], is, Sum(is))
fs := FSlice{0, 1, 2, 3, 4}
fmt.Printf("Sum[%T](%v) = %v\n", fs[0], fs, Sum(fs))
}
USER-DEFINED COLLECTIONS
024_generic_func.go 025_generic_func.go
func main() {
is := ISlice{0, 1, 2, 3, 4}
is2 := append(make(ISlice, 0), is...)
Append(&is2, 5)
fmt.Printf("Append[%T](%v, %v) = %T%v\n", is, is, 5, is2, is2)
fs := []float32{0, 1, 2, 3, 4}
fs2 := append(make([]float32, 0), fs...)
Append(&fs2, 6)
fmt.Printf("Append[%T](%v, %v) = %T%v\n", fs, fs, 6, fs2, fs2)
}
HIGHER ORDER FUNCTIONS
HIGHER ORDER FUNCTIONS
027_high_order_func.go
package main
import "fmt"
func main() {
is := ISlice{0, 1, 2, 3, 4}
fmt.Printf("Sum(%v) = %v\n", is, Sum(is))
}
go run 027_high_order_func.go
Sum([0 1 2 3 4]) = 10
HIGHER ORDER FUNCTIONS
028_high_order_func.go 029_high_order_func.go
go run 029_high_order_func.go
# command-line-arguments
./029_high_order_func.go:13:8: cannot use v (variable of type
float32) as type int in argument to f
HIGHER ORDER FUNCTIONS
030_high_order_func.go
func main() {
is := ISlice{0, 1, 2, 3, 4}
fmt.Printf("Sum(%v) = %v\n", is, Sum(is))
}
HIGHER ORDER FUNCTIONS
032_high_order_func.go
func main() {
is := []int{0, 1, 2, 3, 4}
ir := Reduce(is, func(x, v int) int {
return x + v
})
fmt.Printf("Reduce(%v, f()) = %v [%T]\n", is, ir, ir)
fs := []float32{0, 1, 2, 3, 4}
fr := Reduce(fs, func(x, v float32) float32 {
return x + v
})
fmt.Printf("Reduce(%v, f()) = %v [%T]\n", fs, fr, fr)
}
REDUCING COLLECTIONS
035_reduce.go
func main() {
is := ISlice{0, 1, 2, 3, 4}
ir := is.Reduce(func(x, v int) int {
return x + v
})
fmt.Printf("(%T)%v.Reduce(f()) = %v [%T]\n", is, is, ir, ir)
fs := Reducible[float32]{0, 1, 2, 3, 4}
fr := fs.Reduce(func(x, v float32) float32 {
return x + v
})
fmt.Printf("(%T)%v.Reduce(f()) = %v [%T]\n", fs, fs, fr, fr)
}
REDUCING COLLECTIONS
038_reduce.go
func main() {
im := IMap{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
ir := im.Reduce(func(x, v int) int {
return x + v
})
fmt.Printf("%v.Reduce(f()) = %v [%T]\n", im, ir, ir)
fm := Reducible[int, float32]{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
fr := fm.Reduce(func(x, v float32) float32 {
return x + v
})
fmt.Printf("%v.Reduce(f()) = %v [%T]\n", fm, fr, fr)
}
REDUCING COLLECTIONS
039_reduce.go
go 052_reduce.go
[string]Reduce(01234, f()) = 10[int32]
REDUCING COLLECTIONS
053_reduce.go
package main
import "fmt"
func main() {
DoMap([]int{0, 1, 2, 3, 4})
DoMap([]float32{0, 1, 2, 3, 4})
}
054_map.go
Map([0 1 2 3 4], func()): [0 2 4 6 8]
Map([0 1 2 3 4], func()): [0 2 4 6 8]
MAPPING COLLECTIONS
055_high_order_func.go
func main() {
DoMap[float32](func(x int) (float64, bool) {
return float64(x), (x < 5)
})
}
MAPPING COLLECTIONS
060_map.go
return
}
MAPPING COLLECTIONS
063_map.go
func main() {
DoMap[int]([3]int{0, 1, 2})
DoMap[float32]([3]float32{0, 1, 2})
DoMap[float32]([3]float64{0, 1, 2})
}
MAPPING COLLECTIONS
064_map.go
‣ github.com/feyeleanor/GoGenericsTalk
‣ slideshare.net/feyeleanor
‣ leanpub.com/GoNotebook
‣ gobyexample.com/generics
‣ go.dev/blog/intro-generics
‣ go.dev/doc/tutorial/generics