2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家
函数:对输入执行某些操作
方法:附加到某种类型上执行某些操作
接口:规定某种类型必须拥有哪些方法
方法是带有接收者的函数。
接口是一组方法签名。
如果某种类型实现了这些方法 → 它就自动满足了该接口。
无需显式实现。没有继承。只有行为。
// 函数
func Add(a, b int) int { return a + b }
type Counter struct{ val int }
// 方法(接收者是“附着点”)
func (c Counter) Add(n int) int { return c.val + n }
- 函数与方法 // 函数 func Add(a, b int) int { return a + b }
type Counter struct{ val int }
// 方法(接收者是“附着点”)
func (c Counter) Add(n int) int { return c.val + n }
逻辑相同,风格不同。
对于无状态操作,请使用函数。
当行为归属于某种类型时,请使用方法。
- 接口的粘合作用
type Stringer interface {
String() string
}
type User struct{ Name string }
// 用户类型现在自动实现了字符串化接口
func (u User) String() string { return u.Name }
func Print(s Stringer) { fmt.Println(s.String()) }
func main() {
Print(User{Name: "Alice"}) // 可行!
}
关键点:打印函数并不关心用户类型。它关心的是字符串化方法。
- 转折:函数也可以作为接口 这是一种让人困惑的模式。
// 一个接口
type Handler interface {
Handle(string)
}
// 一个函数类型
type HandlerFunc func(string)
// 技巧:将处理方法附加到函数类型上
func (f HandlerFunc) Handle(s string) {
f(s) // 调用自身
}
// 现在,任何签名为 func(string) 的函数都可以作为处理器使用
func Log(s string) { fmt.Println("日志:", s) }
func main() {
var h Handler = HandlerFunc(Log)
h.Handle("test") // 日志: test
}
这有什么用?
它允许你在需要接口的地方使用简单的函数。
标准库中的超文本传输协议处理函数正是这样工作的。
- 综合应用 go type Greeter interface { Greet() string }
type Person struct{ Name string }
func (p Person) Greet() string { return "你好," + p.Name }
type GreetFunc func() string
func (gf GreetFunc) Greet() string { return gf() }
func Party(g Greeter) { fmt.Println(g.Greet()) }
func main() {
Party(Person{Name: "Bob"}) // 方法
Party(GreetFunc(func() string { // 作为接口的函数
return "惊喜!"
}))
}
黄金法则
接受接口,返回结构体。
函数负责编排。
方法定义类型上的行为。
接口将“做什么”与“怎么做”抽象分离。
轮到你了
你最喜欢标准库中的哪个小型接口?
输入输出读取器?格式化字符串化器?超文本传输协议处理器?
在下方留言 👇
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。