转自:http://studygolang.com/topics/549
Go 没有类,但可以在结构体类型上定义方法。
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { return math.Sqrt(v.Xv.X + v.Y*v.Y) } func main() { v := &Vertex{3, 4} fmt.Println(v.Abs()) }
可以对包中的 任意 类型定义任意方法,而不仅仅是针对结构体。但是,不能对来自其他包的类型或基础类型定义方法。 接收者为指针的方法:方法可以与命名类型或命名类型的指针关联。有两个原因需要使用指针接收者:避免在每个方法调用中拷贝值(如果值类型是大的结构体的话会更有效率);方法可以修改接收者指向的值。
package main import ( "fmt" "math" ) type MyFloat float64 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) } func main() { f := MyFloat(-math.Sqrt2) fmt.Println(f.Abs()) }
接口:接口类型是由一组方法定义的集合。接口类型的值可以存放实现这些方法的任何值。
package main import ( "fmt" "math" ) type Abser interface { Abs() float64 } func main() { var a Abser f := MyFloat(-math.Sqrt2) v := Vertex{3, 4} a = f // a MyFloat 实现了 Abser a = &v // a *Vertex 实现了 Abser // 下面一行,v 是一个 Vertex(而不是 *Vertex) // 所以没有实现 Abser。 a = v fmt.Println(a.Abs()) } type MyFloat float64 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) } type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { return math.Sqrt(v.Xv.X + v.Y*v.Y) }
隐式接口:解藕了实现接口的包和定义接口的包:互不依赖。因此,也就无需在每一个实现上增加新的接口名称,这样同时也鼓励了明确的接口定义。
package main import ( "fmt" "os" ) type Reader interface { Read(b []byte) (n int, err error) } type Writer interface { Write(b []byte) (n int, err error) } type ReadWriter interface { Reader Writer } func main() {
var w Writer // os.Stdout 实现了 Writer w = os.Stdout fmt.Fprintf(w, "hello, writer\n") }
下面列举几个go标准包的接口:
type Stringer struct { String() string }
type error interface { Error() string }
io.Reader 接口有一个 Read 方法:
func (T) Read(b []byte) (n int, err error)
Read 用数据填充指定的字节 slice,并且返回填充的字节数和错误信息。
在遇到数据流结尾时,返回 io.EOF 错误。
package main import ( "fmt" "io" "strings" ) func main() { r := strings.NewReader("Hello, Reader!") b := make([]byte, 8) for { n, err := r.Read(b) fmt.Printf("n = %v err = %v b = %v\n", n, err, b) fmt.Printf("b[:n] = %q\n", b[:n]) if err == io.EOF { break } } }
Web服务器: 包 http 通过任何实现了 http.Handler 的值来响应 HTTP 请求:
type Handler interface { ServeHTTP(w ResponseWriter, r *Request) }
package main import ( "fmt" "log" "net/http" ) type Hello struct{} func (h Hello) ServeHTTP( w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello!") } func main() { var h Hello err := http.ListenAndServe("localhost:4000", h) if err != nil { log.Fatal(err) } }
图片:
type Image interface { ColorModel() color.Model Bounds() Rectangle At(x, y int) color.Color }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
2013-02-27 盘点游戏中的20个坏习惯
2013-02-27 我为什么喜欢Go语言
2013-02-27 如何招聘一个合格的程序员
2013-02-27 Go语言之父谈Go:大道至简
2013-02-27 使用Go语言两三事
2013-02-27 使用Go语言一段时间的感受
2013-02-27 背完这444句,你的口语绝对不成问题了