go 结构体指针 调用函数和 结构体 调用函数有什么区别

想请问一下大佬们,本来是java栈的,大佬们如果可以类比解释一下就更好了QAQ

  1. go 结构体指针调用函数和结构体调用函数有什么区别
  2. go 结构体指针还能通过&找到地址,这个地址什么呀?
    superhero := &SuperMan{Man{"asd",12,1},"sd"}

superhero.SetName("123132") //通过结构体指针调用

fmt.Printf("%p\n",superhero)

fmt.Printf("%p\n",&superhero) //这个是什么呀

superhero1 := SuperMan{Man{"asd",12,1},"sd"}

superhero1.SetName("123132") //通过结构体调用

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


回答:

你用啥调用的并不重要,重要的方法接收器是怎么定义的。

接受器你可以理解为就是一个参数,所以区别就是指针参数与非指针参数的区别。


指针也是一个对象,对象当然就有地址了。


回答:

首先要明确,golang 中的函数和方法的概念,函数可以理解为普通的函数,而方法是面向对象思想,把一个函数绑定到一个类型上(java中的class)变成方法,方法的接收者为该类型,只有该类型的变量可以调用方法;

package main

import "fmt"

type SuperMan struct {

Man

Context string

}

type Man struct {

Name string

Age int

Race int

}

// 方法的接收者是 *SuperMan

// func (s *SuperMan) SetName(name string) {

// s.Name = name

// }

// 方法的接收者是 SuperMan

func (s SuperMan) SetName(name string) {

s.Name = name

}

func main() {

superhero := &SuperMan{Man{"asd", 12, 1}, "sd"}

superhero.SetName("123132") //通过结构体指针调用

fmt.Println(superhero)

fmt.Printf("%p\n", superhero)

fmt.Printf("%p\n", &superhero) // 变量 superhero 是指针类型的变量,存储的是结构体指针,就是说对这个变量取地址就和对普通的变量取地址是一样的

superhero1 := SuperMan{Man{"asd", 12, 1}, "sd"}

superhero1.SetName("123132") //通过结构体调用

fmt.Println(superhero1)

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

}

你可以执行上述代码, 分别观察方法的接收者为 *SuperMan 和 SuperMan时的输出,并尝试理解;

golang 的参数传递是值传递的,所以用*SuperMan指针类型作为方法的接收者,对结构体属性的修改就能体现到调用者上,但是如果使用SuperMan作为方法的接收者,修改的只是方法内传入的一个结构体副本, 对调用者没有任何修改;
修改结构体属性的时候会用结构体指针作为接收者定义方法,如果只是获取属性会使用结构体作为接收者定义方法;

之所以定义的一个方法既能通过结构体调用同时也可以通过结构体指针调用,是因为:

  • 对于使用结构体指针作为接收者的方法, SuperMan 类型的变量是可以取到地址的,只不过是在语言层面进行了隐式取地址
 superhero1.SetName("123132")  等价于 (&superhero1).SetName("123132") 
  • 对于使用结构体作为接收者的方法,*SuperMan 会获取到结构体 SuperMan 的数据
superhero.SetName("123132")  等价于 (*superhero1).SetName("123132") 

以上是 go 结构体指针 调用函数和 结构体 调用函数有什么区别 的全部内容, 来源链接: utcz.com/p/944455.html

回到顶部