Skip to content

Instantly share code, notes, and snippets.

@nictuku
Created May 29, 2011 01:47
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nictuku/997386 to your computer and use it in GitHub Desktop.
Save nictuku/997386 to your computer and use it in GitHub Desktop.
golang union types.
// Objective: demonstrate that there are more use cases
// for union types than previously thought.
// http://groups.google.com/group/golang-nuts/browse_thread/thread/fbde059a7cfd2fa9
//
// Interface inference.
// We already have type inference, so this would be very Go-like:
type typeA int
func (x typeA) A() {}
func (x typeB) C() {}
type typeB int
func (x typeB) B() {}
func (x typeB) C(){}
func doSomething(foo A|B) {
foo.C() // OK because C is contained in both typeA and typeB.
foo.A() // not OK
foo.B() // not OK
}
// A|B would be similar to "type AB union {A; B}", but it's more
// compact yet still clear.
// Union types would improve things like sort package, which is
// currently limited and only works with a limited number of types.
type SortArray union {
string
[]byte
[]float32
[]int64
}
// Union types would work here too:
func (p SortArray) Len() int { return len(p) }
func (p SortArray) Less(i, j int) bool { return p[i] < p[j] }
func (p SortArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p SortArray) Sort() { sort.Sort(p) }
// We could create aliases for builtin unions:
// integers => int8|int16|int32|int64
// float => float32|float64
// So instead of a multitude of methods:
strconv.Atof32()
strconv.Atof64()
// We'd have:
strconv.Atof()
// For example, these:
// func Ftoa64(f float64, fmt byte, prec int) string {
// return genericFtoa(math.Float64bits(f), fmt, prec, &float64info)
// }
// func Ftoa32(f float32, fmt byte, prec int) string {
// // note the type conversion:
// return genericFtoa(uint64(math.Float32bits(f)), fmt, prec, &float32info)
// }
// Would be simply:
// func Ftoa(f float, fmt byte, prec int) string {
// move genericFtoa()'s code here.
// }
// Type switches would still be necessary in many cases,
// but union types would make things safer:
func MarshalNumber(num byte|int|float32) []byte {
switch i := x.(type) {
case byte:
// something
case int:
// something
// Throw a compiler error because the programmer forgot the 'float32' case.
}
// No more 'default' cases!
}
// One would also be tempted to use union types to merge methods such as:
// Regexp.FindAll()
// Regexp.FindAllString()
// But union types wouldn't help much here since these methods
// still have to _return_ a real type, making usage of unions less interesting.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment