

Things I Wish Someone Had Told Me About Go - latch
http://openmymind.net/Things-I-Wish-Someone-Had-Told-Me-About-Go/

======
jgrahamc
_But, without pointer arithmetics or, despite many claims, pass-by-reference,
Go's "pointers" feels like a more flexible form of Java/Ruby/Python/Node/...._

It's not clear from the first example if the writer actually understands
pointers. The example code passes a pointer to a function and then modifies
the pointer, not what it's pointing to. It was no surprise to me that this
wouldn't modify the original thing the pointer was referencing. If they wanted
to modify the pointer itself then they should have passed a * * User not a
*User.

Go does, indeed, have pass-by-reference (use a pointer) or pass-by-value
(don't use a pointer).

~~~
latch
I understand what a pointer is, but it's entirely possible that I still don't
grok Go. Before writing that, I did try:

    
    
        func main() {
          u := &User{Name: "Leto"}
          Modify(&u)
        }
    
        func Modify(u **User) {
          u = &User{Name: "Paul"}
        }
    

With no luck.

~~~
fmstephe
Enjoyed your article. I think that you are a little off the mark with respect
to pointers though.

The simple solution to your first example is to simply write to the Name field
of the struct being pointed too.

<http://play.golang.org/p/D3t0Iv8oG4>

If you want to do complex pointer meddling (and replace the entire struct) you
need this syntax.

<http://play.golang.org/p/tMwHC-k-bu>

As a side note I have personally used pointers to interfaces for doing search
tree reordering. You can really do a lot of useful pointer operations without
pointer arithmetic.

(A link to a quadtree implementation which uses pointers to interfaces, on
line 119)
[https://github.com/fmstephe/location_server/blob/master/quad...](https://github.com/fmstephe/location_server/blob/master/quadtree/quadtree.go)

~~~
pdw
You don't need pointer-to-pointers to replace the entire struct, you can just
do this: <http://play.golang.org/p/2ZUvuyCtwr>

    
    
      func main() {
        u := &User{Name: "Leto"}
        println(u.Name)
        Modify(u)
        println(u.Name)
      }
      
      func Modify(u *User) {
        *u = User{Name: "Paul"}
      }

~~~
Rygu
Looks like C pointer syntax!

~~~
ithkuil
Indeed. They are pointers. You just cannot do pointer arithmetic on them.

In declaration the ' _' goes on the left though. In general Go's syntax
inverts the declaration w.r.t C/C++:

    
    
        a int   vs  int  a
        b *int  vs  int* b
    
        type X int  vs  typedef int X
    

NOTE: you can do unsafe pointer arithmetic using the "unsafe" package. You can
convert any pointer to a unsafe.Pointer and then you can convert it to a
uintptr.

There are also library functions designed to work with that, for example
atomic.AddUintptr that atomically adds an offset to a pointer.

Although not intended as general use, it can be useful in low level library
code. Otherwise you can do pretty much everything using slices.

------
NateDad
The author is obviously new to Go, and that's fine.... here's a clarification
of interfaces:

 _Interface Pointers_

Note that the author of a type that fulfills an interface and the consumer of
a function that takes an interface both have full control over how much data
is copied on a call to the function. You can control whether a type fulfills
an interface, or whether a pointer to the type fulfills the interface. In Go,
it is always easy to tell how much memory is being copied for any function
call.

    
    
      type Jumper interface {
        Jump()
      }
    
      func MakeItJump(j Jumper) {
        // this function doesn't know what's wrapped inside the Jumper interface
        // and doesn't need to care
        j.Jump()
      }
    
      type Foo struct {
        data [10]int64 // array of 10 8 byte numbers = 80 bytes on a copy
      }
      func (f *Foo) Jump() {
        // we define Jump on Foo to take a copy of a pointer to a Foo.
        // this means that when we pass a *Foo into MakeItJump, 
        // just a single pointer value is copied into the interface, \
        // not the whole array inside Foo
      }
    
      type Bar uint8
    
      func (b Bar) Jump() {
        // we define Jump on Bar as taking a copy of the value of Bar
        // since we know it only needs to copy an 8 bit integer to do so
      }

~~~
matthavener
I didn't quite "get" the point of the pointer/copy option on interfaces, but
this makes it crystal clear. This works around such a common problem in
writing C++ templates (which is really the only equivalent polymorphism if you
want to dispatch a function on a native type):

    
    
      template <class T> void doSomething(const T &expensiveCopy);
    

Versus:

    
    
      template <class T> void doSomething(T cheapCopy);
    

As usual, boost provides another crazy template hack to work around this
issue:

<http://boost.sourceforge.net/libs/utility/call_traits.htm>

~~~
esrauch
Can you explain why this is actually a problem? Why not just always have a
const T&, is there some negative in the "cheap copy" case to not copy?

~~~
matthavener
I'm making some assumptions about the compiler optimization: If T is something
like "int", then passing by reference can be more costly, because a value that
was once stored in a register now needs a real memory address and must be
deferenced to read.

------
pkulak
The "interface as a pointer" thing really threw me for a loop as well. It was
bothering me so much (not knowing what was actually going on), and Googling
was helping so little, that I actually hopped on the Go IRC channel. The guys
on there set me straight in, literally, minutes. There's a great community
around Go right now.

Other than that, though, everything has been pretty cut and dry. There really
aren't many "gotchas" in Go.

------
dewitt
That pointer example is a little weird. A C/C++ pointer used that way wouldn't
print "Leto" "Paul", either. All it would do is update the local variable to
point to a new object, but the caller would still be pointing to the original.
I think the poster meant to use a pointer to a pointer here (which would work
as intended in both Go and C/C++).

------
voidlogic
"Tip Or Don't Bother"

This is pretty true, although I would not bother using tip if writing a small
command line utility or learning Go, but for a large project this is good
advice. Execution time and memory usage are greatly improved in tip, at the
cost you might run into bug that has not been fixed yet.

Here is the burn down to Go 1.1's release, when it hits bottom it releases.
<http://swtch.com/~rsc/go11.html#> Go 1.1 RC should be out in April I believe.

Also if you need to pick a Go tip build to use this is useful:
<http://build.golang.org/>

~~~
phasevar
Just how much has execution time improved? I'd love to see some benchmarks.

~~~
voidlogic
If you read the golang-dev google groups mailing list you will see lots of
micro-benchmarks posted for specific commits. The best test is to install both
stable and tip on your machine and compile your application with both. In one
of my application there was a 9% improvement, in another it was 53%. When Go
1.1 is released I presume the computer benchmarks game will be updated, which
might make comparison, at lease with other languages, easier.

------
ISL
Whoa. Pre-coffee, I'd clicked on the link expecting to find a "List of things
someone had told me about the strategy game Go".

Anyone have a link to such a list? Seems like it'd be fun.

~~~
shurcooL
I had the opposite problem.

When someone retweeted this[1], I thought it was about golang problems.

[1] <https://twitter.com/gogameguru/status/309695255056351232>

------
toddh
>func ServeHTTP(res http.ResponseWriter, req *http.Request)

I'd always wondered about that too. Thanks for one less mystery in the world.

------
kin3tic
Wow, this displays a severe misunderstanding of how pointers work in general.
It's not like the syntax for it in Go is any different, this code would look
very similar in anything that has real pointers (C, for example), certainly in
regards to the notation and syntax for pointers and references and such.

'I understand what a pointer is'. Questionable.

~~~
drivebyacct2
For reference, I posted this in a subthread above: the same example in C
demonstrating using a pointer and passing it or declaring an object and
passing it's address: <http://codepad.org/TeUZi1Wp>

~~~
latch
Same example in C# showing pass by reference does exist
<http://rextester.com/IYZE41714>

