generic
Outlinks (0)
No outlinks found
https://go.dev/blog/when-generics:
0.1 · when#
write Go programs by writing code, not by defining types. Start by writing functions, not by defining type parameter constraints.
When using language-defined container types: slices, maps, and channels. If a function has parameters with those types, and the function code doesn’t make any particular assumptions about the element types, then it may be useful to use a type parameter.
General purpose data structures:
// Tree is a binary tree.
type Tree[T any] struct {
cmp func(T, T) int
root *node[T]
}
// A node in a Tree.
type node[T any] struct {
left, right *node[T]
val T
}
// find returns a pointer to the node containing val,
// or, if val is not present, a pointer to where it
// would be placed if added.
func (bt *Tree[T]) find(val T) **node[T] {
pl := &bt.root
for *pl != nil {
switch cmp := bt.cmp(val, (*pl).val); {
case cmp < 0:
pl = &(*pl).left
case cmp > 0:
pl = &(*pl).right
default:
return pl
}
}
return pl
}
// Insert inserts val into bt if not already there,
// and reports whether it was inserted.
func (bt *Tree[T]) Insert(val T) bool {
pl := bt.find(val)
if *pl != nil {
return false
}
*pl = &node[T]{val: val}
return true
}
For type parameters, prefer functions to methods:
Implementing a common method: it’s reasonable to use type parameters when you need to implement methods that look the same for all the relevant types.
0.2 · When are type parameters not useful?#
Don’t replace interface types with type parameters:
func ReadSome(r io.Reader) ([]byte, error)
func ReadSome[T io.Reader](r T) ([]byte, error)
Don’t use type parameters if method implementations differ: if the implementation of a method is the same for all types, use a type parameter. Inversely, if the implementation is different for each type, then use an interface type and write different method implementations, don’t use a type parameter.
Use reflection where appropriate: types that don’t have methods (so that interface types don’t help), and if the operation is different for each type (so that type parameters aren’t appropriate), use reflection.
https://www.bmpi.dev/dev/deep-in-program-language/how-to-implement-generics/
https://mp.weixin.qq.com/s/SJsEurfZr4TG-I3rncid5A
https://colobu.com/2021/08/30/how-is-go-generic-implemented/ https://colobu.com/2021/10/24/go-generic-eliding-interface/