2

I am just starting to study Go and some things caught my attention.

Functions like:

delete(map, "Answer") // for maps
append(slice, 0) // for slices
len(slice), cap(slice) // again for slices

and so on. As someone coming from C like languages, I am wondering:

1) Can these functions be called through the variable itself (as in map.delete("Answer"))?

2) Is this a common practice (defining a generic function and let it figure out the type and what it should do), or is this just for the built in types. For example, if I would define my own type, like MyCoolLinkedList, should I define the len and append functions inside the type and have them called like

list := new(MyCoolLinkedList)
list.len()

or should I define a function that receives the list, like:

len(list)
icza
  • 389,944
  • 63
  • 907
  • 827
Mario Stoilov
  • 3,411
  • 5
  • 31
  • 51

1 Answers1

2

1 - You can't call builtin methods "attached" to types or values, e.g.

m := map[int]string{1: "one"}
m.delete(1)

is a compile time error which you can verify easily.

2 - Go doesn't have generics. But to ease the "pain", it provides several builtin functions which can accept values of different types. They are builtin because –as mentioned– due to the lack of generics, they need the help of the compiler to be able to accept values of different types. Some also accept a type instead of an expression as the first argument (e.g. make([]int, 1)) which is also something you can't create. Builtin functions do not have standard Go types, they can only appear in call expressions.

You can't create such functions that accept values of different types. Having said that, when you create your own type and you create a "function" for it, it is advisable to declare it as a method instead of a helper function; as if the "function" operates on your concrete type, you could not use it for other types anyway.

So it makes sense to declare it as a method, and then you can call it more "elegantly" like

value.Method()

Being a method also "counts" toward the method set of the type, should you need to implement an interface, e.g. in case of your MyCoolLinkedList it would make sense to implement sort.Interface to be able to sort the list, which requires a Len() int method for example.

Choosing a method over a helper function also has the advantage that your method will be available via reflection. You can list and call methods of a type using the reflect package, but you can't do the same with "just" functions.

icza
  • 389,944
  • 63
  • 907
  • 827