无意间发现的一个写法
type T struct {
t int
}
func (t T) NewT(tValue int) T {
return T{t: tValue}
}
func main() {
t := T.NewT(T{},999)
fmt.Println(t)
}
输出 {999}
没有结构体实例,但是却可以直接调用类型来调用对应的方法
t := T.NewT(T{},999)
这写法有点像调用静态方法
通过一些测试可以知道第一个参数的 T{} 必须存在,传入的第一个参数会被当成方法的 reciver 传入方法中(莫非 go 语言是通过这种机制实现的方法调用) 如果方法不去管传入的 reciver 的话,这种写法似乎可以实现类似调用静态方法的写法?
翻了下似乎没找到这种写法的说明,不知道官网有没有对应的地方介绍(也可能是我没找对地方)
1
cmdOptionKana 2020-10-05 10:29:16 +08:00 4
https://golang.org/ref/spec
That function may be called normally with an explicit receiver, so these five invocations are equivalent: t.Mv(7) T.Mv(t, 7) (T).Mv(t, 7) f1 := T.Mv; f1(t, 7) f2 := (T).Mv; f2(t, 7) |
2
SingeeKing 2020-10-05 10:30:44 +08:00 via iPhone 1
Python 和 rust 都是这样
|
3
reus 2020-10-05 11:41:13 +08:00
方法本来就是一个函数,这个函数的第一个参数就是 receiver,所以可以用这个方式调用
|
4
littlewing 2020-10-05 11:52:55 +08:00
t := T.NewT(T{},999)
等价于 t := T{}.NewT(999) |
5
user8341 2020-10-06 07:14:07 +08:00 1
虽然能跑,但是这种写法不太正规。
t := T.NewT(T{},999) 这句的 T{}创建了一个新对象,以传值方式传给 NewT 函数。然后 NewT 函数完全没用到传进来的这个对象, 而是在 return 的时候又创建了一个新的对象 T{t: tValue}, 然后回到 main()函数,它又以复制的方式赋给 t 变量(这又是另一个对象) |
6
reus 2020-10-06 08:50:03 +08:00 via Android
@user8341 如果 receiver 是 T,那调用的时候,就是复制再传参的。所有参数都是复制再传递的。不要以为用对象调用方法,就不会复制。T 和*T 两种 receiver 是有区别的
|
7
sunriz 2020-10-06 11:45:26 +08:00
调用 type.method 实际上就是把 method 的 receiver 暴露为参数了
一般就这两种: 1. type.method(type{},...) 2. (*type).method(new(type),...) 看 method 怎么的定义了 |