Uisng Pointers in Golang

861 views
Skip to first unread message

Abhinav Srivastava

unread,
Nov 1, 2013, 4:42:32 PM11/1/13
to golan...@googlegroups.com
Hi,

I know it is a silly question but very important for me to understand. Can anyone please explain me when to use * in golang? I know the basics about pointers but e.g.
From some blog :

type Client struct {
Name string
Incoming chan string
Outgoing chan string
Conn net.Conn
Quit chan bool
ClientList *list.List
}

and then it creates the function like :

func (c *Client) Read(buffer []byte) bool {
24 bytesRead, error := c.Conn.Read(buffer)
25 if error != nil {
26 c.Close()
27 Log(error)
28 return false
29 }
30 Log("Read ", bytesRead, " bytes")
31 return true
32 }
Here the usage of *Client , please explain and also the linked list is of pointer type. Sorry for this question but I am from JAVA background and never actually tried much to understand pointers.

It would be really helpful if someone could explain the significance with this or any example.

Thanks again.

Regards

Abhinav

Bob Hemington

unread,
Nov 1, 2013, 4:59:16 PM11/1/13
to golan...@googlegroups.com
In Java, everything is seen as an 'object' and passed by reference.

In Go (and other low-level languages) things can be passed by reference or passed by value.

Passing the Client struct in your example by value (not using a *Client pointer) means that Go will create a copy of all those values inside the struct when it is passed to the function. This is faster for small things, like say the int64 (64 bits) type, but is much much slower for things that are larger (lets say an [1024]byte array).

Passing by reference means that the memory is kept in one location, and only a pointer is passed into the function, instead of a copy of all the information.

Additionally, should the Read function in your example want to change data within the Client struct (since you're from Java, think 'class' instance) it must operate on a pointer *Client, otherwise the function would be operating on a copy of that data (think a copy of the 'class' instance) and changes made to it would not translate to other portions of the program.

There are many places online you can read about pointers, I just simplified it a bit in hopes of making it somewhat easier to understand for you. There are probably a few specific technical details I missed that someone will call me out on.

Bob

Eric Johnson

unread,
Nov 1, 2013, 5:03:20 PM11/1/13
to golan...@googlegroups.com
Pointers amount to the difference between pass by reference, and pass by value.

With only a Java background, this would be confusing. In Java, all the primitive types are passed by value, and all the object types are passed by reference.

With a Java function, if you have an "int" parameter, the only way to "modify" the value of that variable

In Java to get pass-by-reference, you need to jump through some hoops, and change your code:

// pass by value
public void myFunction(int foo) {

    // this doesn't change the value for the caller.
    foo = 5
}

If you wanted the caller to receive an updated version of the value:

// pass by reference.
public void myFunction(AtomicInteger foo) {

    // This change will affect what the caller sees
    foo.set(5)
}

In Go

func myFunction(foo int) {
    // caller's copy of the integer unaffected.
    foo = 5
}

func myFunction(foo *int) {
    // caller's copy updated.
    foo = 5
}

Does that help?

Eric.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Rob Pike

unread,
Nov 1, 2013, 5:06:12 PM11/1/13
to Bob Hemington, golan...@googlegroups.com
"In Java, everything is seen as an 'object' and passed by reference."

Except that that's never true. Everything in Java is passed by value.
That's the case almost always in all C-family languages. The call
sin(3.0) doesn't pass a reference to 3.0, it passes the value in C,
C++, Java, Go, ...

The surprise is that Java passes, by value, a pointer to the object in
a method call, but hides the fact that it's a pointer. Java is
confusing matters; it's unfortunate that it's the familiar example
everyone uses as a contrast to explain pointers in Go.

I tire of explaining this to people. I wish the schools taught how
computers work nowadays instead of what the JVM does.

-rob

Henrik Johansson

unread,
Nov 1, 2013, 5:10:40 PM11/1/13
to Eric Johnson, golang-nuts

There is a misconception wrt Java in this which has been around forever it seems. Everything is passed by value in java as well as in Go. Objects work much like slices in Go with a value that refers to underlying data.

Eric Johnson

unread,
Nov 1, 2013, 5:19:37 PM11/1/13
to Henrik Johansson, golang-nuts
Fair point that my wording might be confusing, which was why I provided an example.

I understand the distinction, but I was targeting my message to someone who indicated they have mostly Java experience. It seemed easier to indicate that the object is passed by reference rather than trying to make a slightly more subtle distinction that the pointer to the object is passed by value..

Eric.

Abhinav Srivastava

unread,
Nov 1, 2013, 5:21:30 PM11/1/13
to golan...@googlegroups.com
Thanks a lot..helped me to get some hold of pointers..so even if I pass Client (without the pointer), that would not change the course of things, it would be just a heavy load. Correct me if I am wrong please.

Abhinav Srivastava

unread,
Nov 1, 2013, 5:24:20 PM11/1/13
to golan...@googlegroups.com
thanks eric..got ur point quite clearly..but the example I have provided.. is trying to read something from Client ..so why it should not be just a simple client rather than a pointer. Every client should not have their own copy..sorry if I am sounding confused... 

Eric Johnson

unread,
Nov 1, 2013, 5:30:52 PM11/1/13
to golan...@googlegroups.com
Looks like, for this particular example, the use of

func (c Client) ....

vs.

func (c *Client) ...

probably doesn't matter. This particular instance may boil down to idiomatic usage - if you have a bunch of functions on "(c *Client)", then you may not want to have this one function that can be just "(c Client)", because developers that come after you might not notice the distinction. And then be confused by the bug that tries to change the "Client" object, but nothing happens.

Eric.

Abhinav Srivastava

unread,
Nov 1, 2013, 5:43:25 PM11/1/13
to golan...@googlegroups.com
so if I am not wrong.. then using the pointers in like :

func (c *Client) read ....

will hold the scope for just one client completely and not affecting other copy of client..

if I am calling function "read" for some client c1 and then for c2. then c1 will have its own scope of things and c2 will have own scope of things..Am i right?

Also, I think the linked list should not be of pointer  since it has to change for all..like adding clients and deleting so it has to have just one copy..

Please validate my understanding and sorry if my questions are too silly. 

Gerard

unread,
Nov 1, 2013, 6:37:27 PM11/1/13
to golan...@googlegroups.com
It's quite easy actually. A method can only change a variable when it has a pointer. See this goplay example.

However, if a type contains reference types, these can be changed regardless whether the method has a pointer or not. See this goplay example.

Abhinav Srivastava

unread,
Nov 1, 2013, 6:42:19 PM11/1/13
to golan...@googlegroups.com
Thanks gerard..i think I am clear with pointer thing now..will brush up more with some variations.. 

Thanks everyone..for the help :)

Abhinav Srivastava

unread,
Nov 5, 2013, 11:58:09 PM11/5/13
to golan...@googlegroups.com
Hi again,

package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := Vertex{3, 4}
    fmt.Println(v)
    v.Scale(5)
    fmt.Println(v, v.Abs())
}

Abs() uses the original value of vertex not the scaled value..how do we do that? Since I am using pointer of Vertex, i thought it will reflect the value.

Thanks again.

Regards

Abhinav

Dan Kortschak

unread,
Nov 6, 2013, 12:04:45 AM11/6/13
to Abhinav Srivastava, golan...@googlegroups.com
Why do you think that?

http://play.golang.org/p/NYtawBkvVM

Abhinav Srivastava

unread,
Nov 6, 2013, 12:06:11 AM11/6/13
to golan...@googlegroups.com
really sorry..my bad..i tried other code .. :(
Reply all
Reply to author
Forward
0 new messages