Go 具有指针接收器的方法

Go 具有指针接收器的方法,go,Go,我是计算机科学的新手。我刚刚从Go编程语言中阅读了下面的代码片段,得到了以下错误日志 func (p *Point) ScaleBy(factor float64){ p.X *= 2 p.Y *= 2 } Point{1, 2}.ScaleBy(2) # error log cannot call pointer method on point literal cannot take the address of point literal point literal.scaleby

我是计算机科学的新手。我刚刚从Go编程语言中阅读了下面的代码片段,得到了以下错误日志

func (p *Point) ScaleBy(factor float64){
  p.X *= 2
  p.Y *= 2
}

Point{1, 2}.ScaleBy(2)
# error log
cannot call pointer method on point literal
cannot take the address of point literal
point literal.scaleby(2) used as value
这本书解释说,我们不能在不可寻址的点接收器上调用
*点
方法,因为无法获得临时值的地址


但是,如果我打印
&点{1,2}
,这不会引发错误。因此,为什么
点{1,2}
是不可寻址的点接收器?

当您编写
点{1,2}
时,您只需声明和初始化
类型的值。如果不将其分配给变量,则会将其丢弃

Go不允许对简单值调用指针方法的这种行为,因为指针方法表示修改对象(指针指向)的意图。在大多数情况下,使用值调用指针方法是无用的,因为值是通过copy传递给该方法的。对值所做的任何修改都将对复制的值进行,不会发生实际修改

如果您尝试此方法,它将起作用:

type Point struct {
    x, y int
}

func (p Point) X() {
    fmt.Println(p.x)
}

Point{1, 2}.X() // 1

您可以在此处阅读更多信息:

通过使用
点{1,2}。ScaleBy(2)
您正在尝试调用指针接收器方法
ScaleBy
,其值为:
点{1,2}

任何其他类型T的方法集由声明的所有方法组成 带T型接收器

但如果使用可寻址类型:

对应指针类型*T的方法集是所有 用receiver*T或T声明的方法(也就是说,它还包含 方法集(T)

然后是可能的:这意味着您或编译器应该获得临时值的地址(采用复合文字的地址):

地址操作员:
对于类型为T的操作数x,地址操作&x生成 类型为*T的指针指向x。操作数必须是可寻址的,即, 变量、指针间接寻址或切片索引操作; 或可寻址结构操作数的字段选择器;还是数组 可寻址数组的索引操作。作为一个例外 可寻址性要求,x也可以是a(可能带括号) 复合文字。如果对x的求值会导致运行时错误 惊慌失措,那么对&x的评估也是如此

参考:

您可以调用
(&Point{1,2})。ScaleBy(2)

与此工作示例代码(指针接收器)类似:

主程序包
输入“fmt”
func main(){
p:=(&点{1,2})。ScaleBy(2)
fmt.Println(p)/&{24}
}
类型点结构{
十、 Y整数
}
func(p*点)比例比(因子浮点64)*点{
p、 X*=2
p、 Y*=2
返回p
}
您可以调用
点{1,2}.ScaleBy(2)

与此工作示例代码(值接收器)类似:

主程序包
输入“fmt”
func main(){
p:=点{1,2}。ScaleBy(2)
fmt.Println(p)/&{24}
}
类型点结构{
十、 Y整数
}
func(p点)比例比(因子浮点64)*点{
p、 X*=2
p、 Y*=2
退货与付款
}
输出:

&{2 4}
{2 4}
另请参见此工作示例代码(指针接收器):

主程序包
输入“fmt”
func main(){
p:=点{1,2}
p、 ScaleBy(2)
fmt.Println(p)/{24}
}
类型点结构{
十、 Y整数
}
func(p*点)比例比(因子浮点64){
p、 X*=2
p、 Y*=2
}
输出:

&{2 4}
{2 4}