This entry is targetted as C# developers, those are engaged in Go development.

In Go, maps, channels and slices resemble the same reference type semantic of C#. Meaning With reference types, two variables can reference the same object; therefore, operations on one variable can affect the object referenced by the other variable*.

As shown in the code (Go Playground), for example when we call:

func mutateMap(m map[int]int) {
	m[0] = 66
}

It actually does mutate the state of the map m whilst we are passing the m itself - not a pointer. Yet m gets mutated. The equivalent C# code is:

static void mutateMap(Dictionary<int, int> m)
{
    m[0] = 66;
}

Despite the fact that m is a reference type (map in Go and Dictionary<int, int> in C#) neither of the references themselves can be mutated - just their state/content - unless we use the related syntax (getting the pointer via & operator in Go and via ref keyword in C#).

For example in Go, if we pass a non-nil pointer to this function:


func remakeMap(m *map[int]int) {
	*m = make(map[int]int)
	(*m)[10] = 10
}

Calling it as remakeMap(&m), it will give us a new map and as we see in the output, that new map is actually placed inside variable m. Same functionality/semantic in C# is:

static void remakeMap(ref Dictionary<int, int> m)
{
    m = new Dictionary<int, int>();
    m[10] = 10;
}

C# code can be found here. As you see passing a non-nil pointer to a map, slice or channel to a function in Go is semantically equivalent of passing a reference type using ref parameters to a function/method in C#.

The only collection/container type in Go that is a value type, is array. You can even compare arrays based on their content. All other user defined types in Go are value types (type myType struct { ... }), yet we can pass them either by value or by reference (the pointer). And the semantic is pretty much the same as of C# - for value types and reference types. Interfaces in Go are not data types, but more of a protocol for a type to follow. They are very much like extension methods in C#, just a bit more flexible.