我是计算机科学的新手。我刚刚从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/