熟悉C语言的同学都知道,查看一个变量的地址在处理指针的相关问题的时候直观重要,在C中直接取地址符&即可。那么在Go语言中如何查看一个变量的地址,我们使用unsafe.Pointer() 函数来查看一个变量的内存地址。
举例:
type Vertex struct {
X, Y float64
}
func (v Vertex) sqrt() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
func (v Vertex) scale(f float64) { //带 号 和不带*号的区别 可以从内存地址来看出
fmt.printf("=======", unsafe.Pointer(v))//v 本身就是指针 存储的就是地址 不用取地址
v.X = x.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
fmt.printf("=======", unsafe.Pointer(&v))
v.scale(10)
fmt.Println(v.sqrt())
}
//带 号 打印的结果 ====== -%!(EXTRA unsafe.Pointer=0xc00006e070)======%!(EXTRA unsafe.Pointer=0xc00006e070) 相同
//不带 号 打印的结果 ======%!(EXTRA unsafe.Pointer=0xc000094060)======%!(EXTRA unsafe.Pointer=0xc000094090) 不同
去掉*号 在scale()方法中要对 v 进行取地址操作
golang的指针receiver和非指针receiver的区别?
最大的区别应该是指针传递的是对像的引用,这样在方法里操作的时候可以动态修改对像的属性值。
非指针传递的是对像的拷贝。
这个应该和PHP的引用的用法差不多。
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func (p *Person) SayHi1() {
p.Name = "leon1"
}
func (p Person) SayHi2() {
p.Name = "leon2"
}
func main() {
p1 := &Person{Name: "test", Age: 10}
fmt.Println("name1 : " + p1.Name)
p1.SayHi1()
fmt.Println("name2 : " + p1.Name)
p2 := Person{Name: "test1", Age: 11}
fmt.Println("name3: " + p2.Name)
p2.SayHi2()
fmt.Println("name4 : " + p2.Name)
} name1 : test
name2 : leon1
name3: test1
name4 : test1