diff --git a/CHANGELOG.md b/CHANGELOG.md index 508c4b92..d81ae73d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2023-03-03 + +- Receivers and Interfaces: Clarify subtlety with pointer receivers and values. + # 2022-10-18 - Add guidance on managing goroutine lifecycles. diff --git a/src/interface-receiver.md b/src/interface-receiver.md index 6d4b485e..7addf4ea 100644 --- a/src/interface-receiver.md +++ b/src/interface-receiver.md @@ -20,17 +20,25 @@ func (s *S) Write(str string) { s.data = str } +// We cannot get pointers to values stored in maps, because they are not +// addressable values. sVals := map[int]S{1: {"A"}} -// You can only call Read using a value +// We can call Read on values stored in the map because Read +// has a value receiver, which does not require the value to +// be addressable. sVals[1].Read() -// This will not compile: +// We cannot call Write on values stored in the map because Write +// has a pointer receiver, and it's not possible to get a pointer +// to a value stored in a map. +// // sVals[1].Write("test") sPtrs := map[int]*S{1: {"A"}} -// You can call both Read and Write using a pointer +// You can call both Read and Write if the map stores pointers, +// because pointers are intrinsically addressable. sPtrs[1].Read() sPtrs[1].Write("test") ``` diff --git a/style.md b/style.md index 9d0382b3..f4a9d189 100644 --- a/style.md +++ b/style.md @@ -216,17 +216,25 @@ func (s *S) Write(str string) { s.data = str } +// We cannot get pointers to values stored in maps, because they are not +// addressable values. sVals := map[int]S{1: {"A"}} -// You can only call Read using a value +// We can call Read on values stored in the map because Read +// has a value receiver, which does not require the value to +// be addressable. sVals[1].Read() -// This will not compile: +// We cannot call Write on values stored in the map because Write +// has a pointer receiver, and it's not possible to get a pointer +// to a value stored in a map. +// // sVals[1].Write("test") sPtrs := map[int]*S{1: {"A"}} -// You can call both Read and Write using a pointer +// You can call both Read and Write if the map stores pointers, +// because pointers are intrinsically addressable. sPtrs[1].Read() sPtrs[1].Write("test") ```