Go 使用方法和指针

Go 使用方法和指针,与结构体一样,明白如何使用方法和指针也很重要。您已经看到,方法是一个接受被称为接收者的特殊参数的函数,接收者可以是指针,也可以是值,但两者的差别非常微妙。假设有一个存储三角形数据的结构体。

type Triangle struct {
width float64
height float64
}

为计算三角形的面积,一个简单的公式是将高度和底相乘,再乘以1/2。虽然这可以直接使用结构体的数据字段来计算,但更简结的方式是定义一个方法。方法area返回前述公式的结果。请注意,接收者是指向结构体Triangle的指针,这是由星号指定的。

func (t *Triangle) area() float64 {
return 0.5 * (t.width * t.height)
}

下面程序演示了如何向方法传递指针引用。

 package main

 import (
  "fmt"
 )

 type Triangle struct {
  base float64
  height float64
 }

 func (t *Triangle) area() float64 {
  return 0.5 * (t.base * t.height)
 }

 func main() {
  t := Triangle{base:  3, height:  1}
  fmt.Println(t.area())
 }

执行结果:
Go 使用方法和指针

为理解将接收者参数声明为指针引用和值引用的差别,我们来看一个简单的示例,它修改结构体中定义的三角形的底值。假设要修改三角形的底值,可使用方法changeBase来实现。

func (t Triangle) changeBase(f float64) {
t.base = f
return
}

在这个示例中,注意到指定接收者参数类型时没有在Triangle前面加上星号,这意味着接收者参数是值而不是指针。如下程序是一个完整的示例,它在结构体Triangle的方法集中添加了方法changeBase。

 package main

 import (
  "fmt"
 )

 type Triangle struct {
  base float64
  height float64
 }

 func (t Triangle) changeBase(f float64) {
  t.base = f
  return
 }

 func main() {
  t := Triangle{base:  3, height:  1}
  t.changeBase(4)
  fmt.Println(t.base)
 }

执行结果:
Go 使用方法和指针

之所以打印的是3,是因为方法changeBase接受的是一个值引用。这意味着这个方法操作的是结构体Triangle的副本,而原始结构体不受影响。在方法changeBase中,修改的是原始Triangle结构体的副本的t.base。

将指针作为接收者的方法能够修改原始结构体的数据字段,这是因为它使用的是指向原始结构体内存单元的指针,因此操作的不是原始结构体的副本。

可修改程序清单,将接收者参数的类型声明为指针。这样调用方法时,将修改原始结构体的数据字段。

 package main

 import (
  "fmt"
 )

 type Triangle struct {
  base float64
  height float64
 }

 func (t *Triangle) changeBase(f float64) {
  t.base = f
  return
 }

 func main() {
  t := Triangle{base:  3, height:  1}
  t.changeBase(4)
  fmt.Println(t.base)
 }

执行结果:
Go 使用方法和指针

指针和值之间的差别很微妙,但选择使用指针还是值这一点很简单:如果需要修改原始结构体,就使用指针;如果需要操作结构体,但不想修改原始结构体,就使用值。

酷客教程相关文章:

赞(0)

评论 抢沙发

评论前必须登录!