struct + 方法 → class + dataclass
接收者变成 self,组合保留,隐式接口变成 Protocol —— Go 开发者共鸣感最强的一课。
12 分钟 · 右栏代码可点击「运行」
struct 与方法
Go
1type Server struct {2 Host string3 Port int4}56func (s Server) Addr() string {7 return fmt.Sprintf("%s:%d",8 s.Host, s.Port)9}1011s := Server{Host: "0.0.0.0", Port: 8000}
Python
1from dataclasses import dataclass23@dataclass4class Server:5 host: str6 port: int78 def addr(self) -> str:9 return f"{self.host}:{self.port}"1011s = Server(host="0.0.0.0", port=8000)
- Go 的值接收者/指针接收者选择,在 Python 里不存在:一切皆引用。想保护字段用
frozen=True。 - 构造函数
NewServer(...)由__init__/ dataclass 生成承担,字段名参数调用天然防错位。
隐式接口 → Protocol(static duck typing)
Go
1type Speaker interface {2 Speak() string3}45// 结构体没有 implements 声明,6// 只要方法集满足就自动实现
Python
1from typing import Protocol23class Speaker(Protocol):4 def speak(self) -> str: ...56# 同样没有 implements 声明;7# 结构化匹配由 pyright 静态验证
- 这是 Go 开发者最熟悉的模式,几乎零翻译成本。差异:Python 在运行时才报缺方法(鸭子类型),Protocol 让 pyright 在编辑期就报。
组合 embedding → 组合/继承
Go
1type Logger struct{}2func (Logger) Log(string) {}34type Service struct {5 Logger // 提升方法6 Name string7}
Python
1class Logger:2 def log(self, msg: str) -> None: ...34class Service(Logger): # 继承(或持有一个 logger 属性)5 def __init__(self, name: str):6 self.name = name7 super().__init__()
- Go 没有继承,Python 有但社区同样偏组合。embedding 的「方法提升」效果,用继承或显式委托都能表达。
练一练
这张卡的示例代码已在游乐场中备好,改一改再运行。