https://tour.golang.org/methods/4
刚开始学 go,从 A Tour of Go 开始看的,求大佬帮忙看看,非常感谢
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.Xv.X + v.Yv.Y)
}
func (v *Vertex) Scale(f float64) { //这里 receiver 的类型是 指针类型
v.X = v.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
v.Scale(10) //但是 v 是 Vertex 类型啊?为什么也能运行通过?
fmt.Println(v.Abs())
}
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.Xv.X + v.Yv.Y)
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
var m *Vertex
m = &v //我理解的应该是这样的
m.Scale(10)
fmt.Println(v.Abs())
}
1
heimeil 2019-05-13 11:57:35 +08:00 via Android 1
编译器自动帮你做了你想到的步骤
|
2
icexin 2019-05-13 11:58:51 +08:00 1
为了写代码方便。否则第一个例子你得这么写(&v).Scale(10),go 默认帮你加上了取地址符,前提是变量本身是可以取地址的。
如果你写了一个签名为 func GetVertex() Vertex 的函数,GetVertex().Scale(10)就会失败,因为返回的临时变量不可取地址。 |
3
bef0rewind 2019-05-13 12:17:13 +08:00 via iPhone 1
https://golang.org/ref/spec#Method_values
As with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp. ```go f := t.Mv; f(7) // like t.Mv(7) f := pt.Mp; f(7) // like pt.Mp(7) f := pt.Mv; f(7) // like (*pt).Mv(7) f := t.Mp; f(7) // like (&t).Mp(7) f := makeT().Mp // invalid: result of makeT() is not addressable ``` Although the examples above use non-interface types, it is also legal to create a method value from a value of interface type. ```go var i interface { M(int) } = myVal f := i.M; f(7) // like i.M(7) ``` |
4
lueffy OP 反过来就不行
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func Abs(v Vertex) float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func Scale(v Vertex, f float64) { v.X = v.X * f v.Y = v.Y * f } func main() { v := Vertex{3, 4} Scale(&v, 10) fmt.Println(Abs(v)) } cannot use &v (type *Vertex) as type Vertex in argument to Scale |
5
liangjf 2019-05-13 14:32:41 +08:00
编译器自己加了。。。
|
6
bef0rewind 2019-05-13 14:40:38 +08:00 via iPhone
@lueffy 你的例子错了,这个报错是说参数类型不匹配。
|
7
lueffy OP @bef0rewind 是,评论那个是函数(参数类型不对),不是方法(接收者类型),我搞混淆了
|
8
liulaomo 2019-05-13 23:55:15 +08:00
@lueffy 反过来也是可以的
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { return math.Sqrt(v.X * v.X + v.Y * v.Y) } func main() { v := Vertex{3, 4} fmt.Println((&v).Abs()) } 因为编译器给指针类型*Vertex 隐式声明了一个同名方法。https://gfw.go101.org/article/method.html#implicit-pointer-methods |