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(2) used as value

书中解释说,我们不能在不可寻址的 Point 接收器上调用 *Point 方法,因为无法获取临时值的地址。

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

最佳答案

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

The method set of any other type T consists of all methods declared with receiver type T.

但是如果您使用可寻址类型:

The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T).

那么这是可能的:这意味着您或编译器应该获取临时值的地址(获取复合文字的地址):

Address operators:
For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal. If the evaluation of x would cause a run-time panic, then the evaluation of &x does too.

引用:https://golang.org/ref/spec#Address_operators

您可以调用(&Point{1, 2}).ScaleBy(2)
就像这个工作示例代码(指针接收器):

package main

import "fmt"

func main() {
    p := (&Point{1, 2}).ScaleBy(2)
    fmt.Println(p) // &{2 4}
}

type Point struct {
    X, Y int
}

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

您可以调用Point{1, 2}.ScaleBy(2)
就像这个工作示例代码(值接收器):

package main

import "fmt"

func main() {
    p := Point{1, 2}.ScaleBy(2)
    fmt.Println(p) // &{2 4}
}

type Point struct {
    X, Y int
}

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

输出:

&{2 4}

另请参阅此工作示例代码(指针接收器):

package main

import "fmt"

func main() {

    p := Point{1, 2}
    p.ScaleBy(2)

    fmt.Println(p) //  {2 4}
}

type Point struct {
    X, Y int
}

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

输出:

{2 4}

关于go - 带有指针接收器的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38691587/

相关文章:

go - 带有新旧变量的变量声明和赋值语法

windows - Windows 10 上的 Ansi 颜色,有点不工作

go - 尝试安装 BEEGO 时出错

api - 我可以使用 Go lang 进行自动化测试而不是机器人框架测试吗?

testing - 如何提高 Go 中的测试覆盖率?

go - 返回给定 url 内容的 Web 服务器

go - 将数据范围传递给 HTML 模板

go - 指向表达式结果的指针

Go - 如何加载新的 html 表单

go - Cloud Run从GCS下载文件的速度异常缓慢