[Golang]使用指针类型、指针类型或结构类型调用方法的区别是什么?

huangapple go评论84阅读模式
英文:

[Golang]Different about call a method with pointer type, using point type or struct type?

问题

标题所说的,我不知道在我的情况下使用结构类型还是指针类型调用方法Greeting()时的区别,p.Greeting()u.Greeting()的调用是一样的吗?似乎在调用Greeting()方法时也没有性能上的区别。

我认为u.Greeting()会自动转换为(&u).Greeting()

Go中的一切都是按值传递,但我认为在这种情况下,调用者u是通过引用或指针传递的。

package main

import "fmt"

type User struct {
    Name string
}

func (u *User) Greeting() string {
    u.Name = u.Name + " modify"
    return fmt.Sprintf("Greetings %s!", u.Name)
}

func main() {
    p := &User{"cppgohan by pointer"}
    u := User{"cppgohan by value"}

    fmt.Println(p.Greeting(), p)
    fmt.Println(u.Greeting(), u)
}

输出:

Greetings cppgohan by pointer modify! &{cppgohan by pointer modify}
Greetings cppgohan by value modify! {cppgohan by value modify}
英文:

Like the title said, I don't know the different when I use the struct type or pointer type when call the method Greeting() in my case, does the call p.Greeting() and u.Greeting() just same? Seems no performance different either, when call the Greeting() method.

I think u.Greeting() is automatically convert to (&u).Greeting()?

Everything in Go is passed by value, but I think in this case, the caller u is passing by reference or pointer.

package main

import "fmt"

type User struct {
    Name string
}

func (u *User) Greeting() string {
    u.Name = u.Name+" modify"
    return fmt.Sprintf("Greetings %s!", u.Name)
}

func main() {
    p := &User{"cppgohan by pointer"}
    u := User{"cppgohan by value"}
	
    fmt.Println(p.Greeting(), p)
    fmt.Println(u.Greeting(), u)
}

Output:

Greetings cppgohan by pointer modify! &{cppgohan by pointer modify}
Greetings cppgohan by value modify! {cppgohan by value modify}

答案1

得分: 2

对于p,调用Greeting()就是调用p.Greeting(),对于u,调用(&u).Greeting()

示例:

func (u *User) Greeting() string {
    return fmt.Sprintf("Greetings %s [%p]!", u.Name, u)
}

func main() {
    p := &User{"cppgohan by pointer"}
    u := User{"cppgohan by value"}
    pu := &u

    fmt.Printf("[%p] %v %v\n", pu, pu.Greeting(), pu)
    fmt.Printf("[%p] %v %v\n", &u, u.Greeting(), u)
    fmt.Printf("[%p] %v %v\n", p, p.Greeting(), p)
}

输出:

[0x1030e0e0] Greetings cppgohan by value [0x1030e0e0]! &{cppgohan by value}

[0x1030e0e0] Greetings cppgohan by value [0x1030e0e0]! {cppgohan by value}

[0x1030e0d8] Greetings cppgohan by pointer [0x1030e0d8]! &{cppgohan by pointer}

注意前两个输出具有相同的地址,因为它被隐式转换为指针。

英文:

For p, calling Greeting() is simply calling p.Greeting(), for u it's calling (&u).Greeting().

Example:

func (u *User) Greeting() string {
    return fmt.Sprintf("Greetings %s [%p]!", u.Name, u)
}

func main() {
    p := &User{"cppgohan by pointer"}
    u := User{"cppgohan by value"}
    pu := &u

    fmt.Printf("[%p] %v %v\n", pu, pu.Greeting(), pu)
    fmt.Printf("[%p] %v %v\n", &u, u.Greeting(), u)
    fmt.Printf("[%p] %v %v\n", p, p.Greeting(), p)
}

Output:

> [0x1030e0e0] Greetings cppgohan by value [0x1030e0e0]! &{cppgohan by value}
>
> [0x1030e0e0] Greetings cppgohan by value [0x1030e0e0]! {cppgohan by value}
>
> [0x1030e0d8] Greetings cppgohan by pointer [0x1030e0d8]! &{cppgohan by pointer}

Notice how the first 2 have the same address because it's implicitly converted to a pointer.

huangapple
  • 本文由 发表于 2014年7月23日 01:57:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/24894479.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定