Hacker News new | ask | show | jobs
by dondraper36 671 days ago
No, it's not the case and this terminology shouldn't be used as it's confusing and unhelpful.

There are reference types in Go even though this is also not a super popular term. They still follow the pass-by-value semantics, it's just that a pointer is copied. A map is effectively a pointer to hmap data structure.

In the early days of Go, there was an explicit pointer, but then it was changed.

Slices are a 3-word structure internally that includes a pointer to a backing array and this is why it's also a "reference type".

That said, everything is still passed by value and there are no references in Go.

1 comments

You are splitting hair, Maps are effectively references.

That's like saying C++ doesn't have references since it's just a pointer being copied around

No, there is a real difference, this is not splitting hairs.

Go is always pass-by-value, even for maps [0]:

  x := map[int]int{1: 2}
  foo(x)
  fmt.Printf("%+v", x) //prints map[1:2]

  func foo(a map[int]int) {
    a = map[int]int{3: 4}
  }
In contrast, C++ references have different semantics [1]:

  std::map<int, int> x {{1, 2}};
  foo(x);
  std::print("{%d:%d}", x.begin()->first, x.begin()->second);
  //prints {3:4}

  void foo(std::map<int, int>& a) {
    a = std::map<int, int> {{3, 4}}; 
  } 
[0] https://go.dev/play/p/6a6Mz9KdFUh

[1] https://onlinegdb.com/j0U2NYbjL

foo is receiving a mutable reference and it can't modify the map without those changes leaking out permanently to the caller: https://go.dev/play/p/DXchC5Hq8o8. Passing maps by value would have prevented this by copying the contents.

It's a quirk of C++ that reference args can't be replaced but pointer args can.

The point is that the local variable referencing the map is a different entity than the map itself. Foo gets a copy of that local variable, and the copy references the same map object.

And the fact that C++ references can be used for assignment is essentially their whole point, not "a quirk".