go语言方法集的一些延伸思考

本文探讨了Go语言中方法集规则背后的逻辑,比较了值接收者和指针接收者在实现接口时的差异,并质疑了为何会有这种设计。作者提出疑问,为何不提供更灵活的隐式转换,以实现'优雅'的编程。通过实例解析,揭示了编译器在方法调用时的特殊处理和规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

go语言方法集

规则

先介绍一下go语言的方法集规则:

在这里插入图片描述
意思是:如果使用指针接收者来实现一个接口,那么只有指向那个类型的指针才能够实现对应的接口。如果使用值接收者来实现一个接口,那么那个类型的值和指针都能够实现对应的接口。

示例

光说理论可能比较难理解,看代码:

package main

import "fmt"

type notifyInterface interface {
	notify()
}

func sendEmail(n notifyInterface) {
	n.notify()
}

type user struct {
	name  string
	email string
}

func (u *user) notify() {
	fmt.Printf("Sending user email to %s<%s>\n",
		u.name,
		u.email)
}
func main() {
	u1 := user{
		name:  "john smith",
		email: "john@yahoo.com",
	}
	sendEmail(u1)
}

这个代码是有问题的,报错如下:

.\main.go:29:12: cannot use u1 (variable of type user) as type notifyInterface in argument to sendEmail:
	user does not implement notifyInterface (notify method has pointer receiver)

原因很简单,因为违反了go语言的方法集规则,值类型user没有实现notify方法(notify:是你的指针实现的我,我和你不熟,快爬快爬)

但是如果反过来,把notify的接受者改成值类型:

func (u user) notify() {
	fmt.Printf("Sending user email to %s<%s>\n",
		u.name,
		u.email)
}

那么无论是指针类型,或是值类型的user都能接受。好像值类型就天生比指针类型高级一点(可以这样辅助记忆)。

问题

那么问题来了,为什么会有这么看上去不”优雅“的设计呢?凭什么值类型天生比指针类型高级?我要打拳了(不是)!

书上是这么解释的:编译器并不是总能自动获得一个值的地址

那么问题又来了,什么时候编译器可以自动获取一个值的地址?

根据我目前的学习结果,答案是 当值为方法的调用者时

go语言编译器为方法调用者提供了非常甜的语法糖:

type user struct {
   name  string
   email string
}

func (u user) notify() {
   fmt.Printf("Sending user email to %s<%s>\n",
      u.name,
      u.email)
}
func main() {
   u1 := user{
      name:  "john smith",
      email: "john@yahoo.com",
   }
   u1.notify()
}

在这里notify的接受者类型和notify的调用者类型可以组出四种组合而不报错:

func (u user) notify()
 u1.notify()

func (u *user) notify()
 u1.notify()

func (u user) notify()
(&u1).notify()

func (u *user) notify()
(&u1).notify()

方法的调用者如果是地址,可以被转化为值;如果是值可以被转化为指针。

编译器你给我听好了!那如果这样的糖都能实现,那我教教你应该怎么做才足够“优雅”,还是方法集的错误示例代码:

package main

import "fmt"

type notifyInterface interface {
	notify()
}

func sendEmail(n notifyInterface) {
	n.notify()
}

type user struct {
	name  string
	email string
}

func (u *user) notify() {
	fmt.Printf("Sending user email to %s<%s>\n",
		u.name,
		u.email)
}
func main() {
	u1 := user{
		name:  "john smith",
		email: "john@yahoo.com",
	}
	sendEmail(u1)
}

咱们就先把值类型的user放行sendEmail方法里进来,你先别惦记你那方法集规则了!然后再通过你强大的隐式转化之后去调用notify方法,这样sendEmail方法里的参数是什么类型都不重要了,反正作为调用者可以支持与接受者各种类型的组合,完成了类型的解耦,是不是非常的“优雅”?

编译器:说的好!但在我这就是要先检查方法集规则,是不可能放你一个值类型进入sendEmail方法的!

我:啊这。。。。。。。。

说人话

以上就是我的一些思考,这个方法集规则和方法调用者的语法糖真的让我感到一股违和感。。。。。当然我知道自己是初学go,水平不足,设计go的大牛肯定想的更多,但我作为初学者确实感觉到一点奇怪,到底为什么要设置这个方法集规则呢?为什么不提供随时随地的值和地址之间的隐式的转化呢?
这篇文章就是我的自言自语,可能哪些地方有明显的逻辑漏洞啥的请帮我指出来~知道原因的大佬们也麻烦指导指导吧~

<think>嗯,用户让我介绍如何写一个体现思考的优快云账号。首先,我需要理解用户的需求。可能他们是想在优快云上建立一个技术博客,但希望内容不仅仅是代码分享,而是能展示自己的思考过程,比如解决问题的方法、学习心得或者技术深度分析。这样的话,账号会更有个性,吸引更多读者。 接下来,我得考虑优快云的主要用户群体。优快云是中国最大的IT技术社区,用户大多是开发者、学生和技术爱好者。因此,内容需要兼顾专业性和易懂性。用户可能希望自己的账号既能展示技术实力,又能帮助他人,同时提升个人品牌。 然后,思考如何“体现思考”。这可能包括记录学习过程、解决问题的思路、错误调试的经历,或者对新技术的研究分析。用户需要具体的建议,比如文章结构、内容方向,甚至如何与读者互动。 还要考虑用户可能的深层需求。他们可能不只是想写博客,而是想建立个人品牌,或者找工作、接项目。因此,账号的专业度和深度很重要。需要建议他们保持一致性,比如固定的板块、定期更新,以及如何优化SEO,增加曝光。 另外,需要注意避免泛泛而谈,要具体。比如,可以举例说明如何分解问题,如何记录调试过程,或者如何结合理论与实践。同时,提醒用户保持互动,回复评论,参与社区讨论,增加账号活跃度。 最后,检查是否有遗漏的点。比如,是否需要提到使用Markdown、代码片段、图表等来提升文章可读性?或者是否需要讨论如何选择热门技术话题与个人兴趣结合?这些都可能帮助用户更好地规划内容。 总结下来,回答需要结构清晰,分点说明,涵盖定位、内容方向、写作技巧、互动维护等方面,并给出具体例子,让用户有实际操作的参考。</think>创建一个体现深度思考的优快云技术账号,需要兼顾专业性、个人风格与读者价值。以下是关键设计方向和示例框架: --- ### **1. 账号定位:打造个人技术IP** - **核心领域**:明确细分方向(如「AI工程化」「前端性能优化」「分布式系统踩坑录」) - **人设标签**:思考开发者 ≠ 搬运工,例如: - 「从Kaggle竞赛到工业落地的模型调优手记」 - 「十年后端老兵的架构反思日志」 - **视觉符号**:统一封面设计/代码配色/手绘技术图解风格 --- ### **2. 内容设计:展现思维过程** #### ▶ **技术深挖类** - **标题示例**: 《Redis分布式锁:我为什么最终放弃了Redlock算法?》 《TensorFlow动态Shape优化:三天Debug重构实录》 - **内容结构**: 问题场景 → 直觉方案 → 失败原因 → 思维转折点 → 最终方案对比 → 延伸思考 #### ▶ **学习路径类** - **标题示例**: 《自学Rust三个月:从语法到恐惧管理的认知迭代》 《系统调优书单:为何我建议先读<性能之巅>再碰源码?》 - **内容亮点:** 知识地图绘制 + 关键卡点心理记录 + 反常识结论(附实验数据) #### ▶ **行业洞察类** - **标题示例**: 《大模型时代:为什么说Prompt工程将重定义软件测试?》 《从K8s弃用Docker看云原生演进的暗线逻辑》 - **写作技巧**: 技术趋势交叉分析(附Gartner曲线改造图) + 对工程师的实质影响 -- ### **3. 增强记忆点的技巧** - **系列专栏化**: 《重构启示录》系列(每期解剖一个祖传代码改造案例) 《源码迷踪》系列(结合UML时序图追踪框架设计思想) - **互动创新**: 文末抛出开放技术选择题(如方案A/B优劣投票) 定期发布「读者问题诊断室」专题 - **多模态表达**: 复杂逻辑配自制动图解说 关键结论用Latex公式强化呈现 --- ### **4. 运营策略** - **更新节奏**:双周更深度长文 + 每周碎片化思考(用「技术札记」标签分类) - **流量撬动**: 参与优快云「开发者生态研究」等专栏征稿 关键文章同步至GitHub的README(导流到个人项目) - **数据闭环**: 在文末添加「知识溯源」板块(附相关论文/工具链/Git commit记录) --- ### **示例账号结构** ```markdown 【账号ID】TechThinker算法手札 📜 置顶文章: 《我的技术写作原则:不写重复造轮子指南》 《2024年技术关注清单:五个被低估的研究方向》 🗂 专栏分类: ▷ 机器学习反模式研究(12篇) ▷ 读源码的艺术(7篇) ▷ 高效能开发者的工具哲学(9篇) 🌟 爆款案例: 《放弃Python转Go:我们团队在AI基础设施上的教训》 - 阅读15w+,引发语言战争讨论 《记一次失败的微服务改造:从充血到贫血架构的退化》 - 被多个公司内部分享引用 ``` --- 通过持续输出「有技术增量+认知差异性」的内容,此类账号可实现: ✅ 建立行业影响力 ✅ 吸引高质量人脉(猎头/技术合伙人邀约) ✅ 反向促进自身技术体系化 关键要诀:**把写作当作深度学习的催化剂**,让思考可见化形成复利效应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值