1. 指针作为函数参数

go语言中指针作为函数参数时基本和C语言相同。先看代码
  1. package main
  2. import (
  3.    "fmt"
  4. )
  5. func UpdateA(x int) {
  6.    x = 5
  7. }
  8. func UpdateB(x *int) {
  9.    //x = 5 //compile error
  10.    *x = 5
  11. }
  12. func main() {
  13.    a := 4
  14.    UpdateA(a)
  15.    fmt.Printf("a = %d\n", a)
  16.    b := 4
  17.    //UpdateB(b) //compile error
  18.    UpdateB(&b)
  19.    fmt.Printf("b = %d\n", b)
  20. }
运行
  1. # go run func.go
  2. a = 4
  3. b = 5

2. 方法中的指针

go语言的结构体类似于C++中的类,可以包含属性和方法。
如:
  1. package main
  2. import (
  3.    "fmt"
  4. )
  5. type Cat struct {
  6.    age int
  7. }
  8. func (cat Cat) Age() int {
  9.    return cat.age
  10. }
代码中创建了一个Cat结构体,其中age是结构体的属性,Age()是结构体方法。

给对象分配内存可以用如下几种方式:
  1. cat := new(Cat) //返回Cat对象指针
  2. cat := &Cat{1} //内部会调用new(Cat),返回Cat对象指针
  3. cat := Cat{1} //返回Cat对象

但是,如果Cat结构体中有指针方法,就只能创建Cat对象指针
给上面的Cat结构体添加一个指针方法:
  1. func (cat *Cat) SetAge(x int) {
  2.    cat.age = x
  3. }
go编译器规定此时只能创建Cat对象指针,如果创建Cat对象会出错:
  1. cat := Cat{1} //compile error


3. 调用方法时的指针使用

对于方法的调用,go和C++不同,go比较智能,指针方法和值方法都可以通过指针或非指针对象调用。例如:
  1. type Cat struct {
  2.    age int
  3. }
  4. func (cat Cat) Age() int {
  5.    return cat.age
  6. }
  7. func main() {
  8.    cat := new(Cat) //返回Cat对象指针
  9.    age := cat.Age()//同age := (*cat).Age()
  10.    fmt.Printf("%d\n", age)
  11. }
代码中定义了结构体Cat的Age()方法,通过关键词new生成一个Cat对象指针,我们可以通过cat.Age()或(*cat).Age()访问Age()方法。

如果代码修改成:
  1. func (cat *Cat) Age() int {
  2.    return cat.age
  3. }
  4. func main() {
  5.    cat := Cat{age:1} //返回Cat对象
  6.    age := cat.Age()//同age := (&cat).Age()
  7.    fmt.Printf("%d\n", age)
  8. }
结构体Cat定义了指针方法Age(),main()函数中生成了一个Cat的对象cat,可以通过cat.Age()或(&cat).Age()访问Age()指针方法。

可见,go语言中结构体调用方法是很灵活的,编译过程中会自动完成转换。


4. 指针方法和值方法

和函数类似,指针方法可以修改结构体中的属性值,值方法由于传递的参数是结构体对象的副本,不能改变其属性值。测试代码如下:
  1. package main
  2. import (
  3.    "fmt"
  4. )
  5. type Cat struct {
  6.    age int
  7. }
  8. func (cat Cat) Age() int {
  9.    return cat.age
  10. }
  11. func (cat Cat) SetAge(x int) {
  12.    cat.age = x
  13. }
  14. type Dog struct {
  15.    age int
  16. }
  17. func (dog Dog) Age() int {
  18.    return dog.age
  19. }
  20. func (dog *Dog) SetAge(x int) {
  21.    dog.age = x
  22. }
  23. func main() {
  24.    cat := new(Cat)
  25.    cat.SetAge(5)
  26.    fmt.Printf("%d\n", cat.Age())
  27.    dog := new(Dog)
  28.    dog.SetAge(5)
  29.    fmt.Printf("%d\n", dog.Age())
  30. }
运行:
  1. # go run struct.go
  2. 0
  3. 5
cat的age没被修改,所以是默认初始值0,dog的age被修改了。


以上就是go语言中指针使用的简单说明,总体来说go的指针处理比C语言规则更宽松,但个人感觉这反而容易让初学者混淆。

12-23 09:06