FAQ
Why Golang decides the "Sting()" argument is actually a copy but not the reference?


package main


import "fmt"


type Student struct {

     name string

     age int

}


func (s Student) String() string {

     fmt.Printf("%p\n", &s) //It shows that the s is actually a copy, if the function is declared as "func (s *Stude///nt) String() string" then it will not be called

     return fmt.Sprintf("name is %s\n", s.name)

}


func main() {

     s := Student{name: "charlie", age: 18}

     fmt.Printf("%p\n", &s)

     fmt.Println(s)

}


output:

0x2081c2000

0x2081c2040

name is charlie


as it shows, the argument passing to String() is actual a copy of the object, is that a waste of efficiency?

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Athiwat at Dec 8, 2014 at 1:58 am
    They are still pointing to the same underlying string.
    http://blog.golang.org/slices
    On Mon, Dec 8, 2014, 8:54 AM null wrote:

    Why Golang decides the "Sting()" argument is actually a copy but not the reference?


    package main


    import "fmt"


    type Student struct {

    name string

    age int

    }


    func (s Student) String() string {

    fmt.Printf("%p\n", &s) //It shows that the s is actually a copy, if the function is declared as "func (s *Stude///nt) String() string" then it will not be called

    return fmt.Sprintf("name is %s\n", s.name)

    }


    func main() {

    s := Student{name: "charlie", age: 18}

    fmt.Printf("%p\n", &s)

    fmt.Println(s)

    }


    output:

    0x2081c2000

    0x2081c2040

    name is charlie


    as it shows, the argument passing to String() is actual a copy of the object, is that a waste of efficiency?

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dan Kortschak at Dec 8, 2014 at 1:58 am
    The string data is the same, but the header is a copy.
    On Sun, 2014-12-07 at 17:53 -0800, hust_ch@163.com wrote:
    Why Golang decides the "Sting()" argument is actually a copy but not
    the reference?

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dan Kortschak at Dec 8, 2014 at 3:23 am
    Why not? Which part?

    The other answer in this thread that points to the slices article makes
    it clear why it works this way.
    On Mon, 2014-12-08 at 10:50 +0800, hust_ch wrote:

    Well, I am not sure this is a defect of design or not, but this working way doesn's sound reasonable.
    Anyway, thanks very much for explaination.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dave Cheney at Dec 8, 2014 at 3:34 am

    On Monday, 8 December 2014 12:53:49 UTC+11, hus...@163.com wrote:
    Why Golang decides the "Sting()" argument is actually a copy but not the reference?


    package main


    import "fmt"


    type Student struct {

    name string

    age int

    }


    func (s Student) String() string {

    fmt.Printf("%p\n", &s) //It shows that the s is actually a copy, if the function is declared as "func (s *Stude///nt) String() string" then it will not be called

    return fmt.Sprintf("name is %s\n", s.name)

    }

    You have declared the String method to be on the Student value type, not
    *Student. Method calls in go _ALWAYS_ copy the receiver, they are in effect
    func String(s Student) string. This is why the address of s differs from
    the caller's.

    func main() {

    s := Student{name: "charlie", age: 18}

    fmt.Printf("%p\n", &s)

    fmt.Println(s)

    }


    output:

    0x2081c2000

    0x2081c2040

    name is charlie


    as it shows, the argument passing to String() is actual a copy of the object, is that a waste of efficiency?
    No, consider this func Print(s string) { .. }

    You can see from above this function takes exactly the same number of
    arguments, 1, a two word structure for the string header.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Carlos Castillo at Dec 8, 2014 at 2:19 pm
    Tip: Use the go playground at play.golang.org to post code.

    The reason why you can't use a String() method with a pointer receiver is
    because when passed to Println, it is stored in an interface, and you can't
    get the address of a value stored in an interface to call the method.

    Here are an in-depth set of examples: http://play.golang.org/p/uQL_RMJ_Bj

    The efficiency of passing a 24-byte struct by value vs. a pointer (8-bytes)
    isn't that big an issue several reasons.

        1. To access the fields in the method, you must dereference the pointer,
        so the pointer method could in fact be slower in some situations.
        2. Copies are very cheap for small values
        3. If the function/method is inlined, the copy could be elided by the
        optimizer
        4. If the function/method is not inlined, the copy is likely
        insignificant compared to the cost of calling the function/method.

    This doesn't mean that you should never use pointer receivers:

        1. You can't modify the original object with a value receiver (copy gets
        modified instead)
        2. If there is only supposed to be conceptually one instance of the
        object (eg: a counter or lock), then you shouldn't use a value receiver,
        often due to #1
        3. For large types, especially in the case of simple methods, the copy
        cost is likely a significant part of the total method cost
        4. It usually a good idea to have all the methods following a single
        style, either all pointer receivers or all value receivers

    On Sunday, December 7, 2014 5:53:49 PM UTC-8, hus...@163.com wrote:

    Why Golang decides the "Sting()" argument is actually a copy but not the reference?


    package main


    import "fmt"


    type Student struct {

    name string

    age int

    }


    func (s Student) String() string {

    fmt.Printf("%p\n", &s) //It shows that the s is actually a copy, if the function is declared as "func (s *Stude///nt) String() string" then it will not be called

    return fmt.Sprintf("name is %s\n", s.name)

    }


    func main() {

    s := Student{name: "charlie", age: 18}

    fmt.Printf("%p\n", &s)

    fmt.Println(s)

    }


    output:

    0x2081c2000

    0x2081c2040

    name is charlie


    as it shows, the argument passing to String() is actual a copy of the object, is that a waste of efficiency?
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedDec 8, '14 at 1:53a
activeDec 8, '14 at 2:19p
posts6
users5
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase