golang2021面向对象(19)表达式
Golang 表达式 :根据调用者不同,方法分为两种表现形式:
instance.method(args...) ---> .func(instance, args...)
前者称为 method value,后者 method expression。
两者都可像普通函数那样赋值和传参,区别在于 method value 绑定实例,而 method expression 则须显式传参。
package main
import "fmt"
type User struct {
id int
name string
}
func (self *User) Test() {
fmt.Printf("%p, %v ", self, self)
}
func main() {
u := User{1, "Tom"}
u.Test()
mValue := u.Test
mValue() // 隐式传递 receiver
mExpression := (*User).Test
mExpression(&u) // 显式传递 receiver
}
输出结果:
0xc42000a060, &{1 Tom}
0xc42000a060, &{1 Tom}
0xc42000a060, &{1 Tom}
需要注意,method value 会复制 receiver。
package main
import "fmt"
type User struct {
id int
name string
}
func (self User) Test() {
fmt.Println(self)
}
func main() {
u := User{1, "Tom"}
mValue := u.Test // 立即复制 receiver,因为不是指针类型,不受后续修改影响。
u.id, u.name = 2, "Jack"
u.Test()
mValue()
}
输出结果
{2 Jack}
{1 Tom}
在汇编层面,method value 和闭包的实现方式相同,实际返回 FuncVal 类型对象。
FuncVal { method_address, receiver_copy }
可依据方法集转换 method expression,注意 receiver 类型的差异。
package main
import "fmt"
type User struct {
id int
name string
}
func (self *User) TestPointer() {
fmt.Printf("TestPointer: %p, %v ", self, self)
}
func (self User) TestValue() {
fmt.Printf("TestValue: %p, %v ", &self, self)
}
func main() {
u := User{1, "Tom"}
fmt.Printf("User: %p, %v ", &u, u)
mv := User.TestValue
mv(u)
mp := (*User).TestPointer
mp(&u)
mp2 := (*User).TestValue // *User 方法集包含 TestValue。签名变为 func TestValue(self *User)。实际依然是 receiver value copy。
mp2(&u)
}
输出:
User: 0xc42000a060, {1 Tom}
TestValue: 0xc42000a0a0, {1 Tom}
TestPointer: 0xc42000a060, &{1 Tom}
TestValue: 0xc42000a100, {1 Tom}
将方法 "还原" 成函数,就容易理解下面的代码了。
package main
type Data struct{}
func (Data) TestValue() {}
func (*Data) TestPointer() {}
func main() {
var p *Data = nil
p.TestPointer()
(*Data)(nil).TestPointer() // method value
(*Data).TestPointer(nil) // method expression
// p.TestValue() // invalid memory address or nil pointer dereference
// (Data)(nil).TestValue() // cannot convert nil to type Data
// Data.TestValue(nil) // cannot use nil as type Data in function argument
}
发行虚拟货币需要几步?现在发行虚拟货币真的很简单,杠精不要不经过调查就来杠!所有虚拟货币上主网都会开源自己的代码,只需要复制粘贴,熟练点的人十分钟就能搞一个虚拟货币。三步搞定第一,复制代码。第二,改名字
为什么坚定看好新能源基建?去年四季度以来,我对新能源赛道的关注点逐步从上游设备商组件商转移到新能源基建子赛道,核心逻辑在于市场竞争格局的快速变化,上游设备组件环节由于扩张壁垒不高导致产能快速膨胀,产能严重过
新能源的市场怎么样零跑C11放到同价位的燃油车中比较,也同样具有相当强的竞争力。就拿动力操控来说,售价19。98万的零跑C11性能版配备了400kW电机,峰值扭矩可以达到720Nm,4。8秒即可破百
终于等到腾讯今天腾讯的意外跳水大跌,坊间一片惊恐。但对于鸟哥来说,正是一个期待已久,终于发生的事件,淡定中略有喜悦。没有人知道腾讯为何突然跳水,有传言说有版号利空等等,最终都被否认。事实上,鸟
无人驾驶真的可行吗?汽车无人驾驶普及主要受到两个因素控制一个是技术成熟度的问题,一个是市场需求的问题。技术成熟度主要是人工智能,人工智能主要细分技术包括,计算机视觉与深度学习。同时以传感器以及高速芯片
iPhone14外观升级硬件更强价格很香,网友感慨这才是真旗舰在过去的两年里,苹果在手机市场上的表现非常出色。它不仅经常在中国的京东平台上赢得每月的销售冠军,而且还在全球市场上追逐三星。如果不考虑销售和利润,苹果显然已经成为手机市场上最亮的明
Golang入门到项目实战golang关键字continuecontinue只能用在循环中,在go中只能用在for循环中,它可以终止本次循环,进行下一次循环。在continue语句后添加标签时,表示开始标签对应的循环。go语言continu
2022买手机眼光要放长远,这三款旗舰机,用四五年轻而易举初春伊始,最近很多朋友打算购入新机,很多人来咨询小编有什么推荐?根据长期使用体验拉满的原则,以下三台旗舰机,虽然贵点,但真的值得入手。一加10Pro这款手机可以说是硬核玩家的梦中情
苹果在荷兰再被罚500万欧元金额累计达2500万欧元据国外媒体报道,荷兰反垄断监管机构周一再次对苹果开出500万欧元的罚单,苹果对于荷兰交友应用程序替代支付系统的解决方案依仍然不符合反垄断机构的要求,这已经是其对苹果发出的第五次同类
苹果为什么到现在,都没有采用曲面屏?保持辨识度很重要自从全面屏时代开启之后,手机在外形设计方面就有了更多的可能性。全面屏的概念,很多人说来自于三星,这是三星在这方面做到了都属于自己的特色,并且也将全面屏技术沿用到了很多其他手机厂商制
申通快递1元购备受争议深交所问询函直指其合理性财联社新消费日报(记者李丹昱)讯,申通快递在情人节当天发布员工持股计划后,市场反应强烈。由于员工购买的价格仅为1元股,且参加对象以管理人员为主,申通快递股价一路走低。2月22日午间