30分钟上手GO语言--方法和接口

iori84888340 · · 3267 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。
方法和接口 这章讲如何为类型定义方法;如何定义接口;以及如何将所有内容贯通起来。 方法:Go 没有类,但可以在结构体类型上定义方法。 package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.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.X*v.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 }

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

3267 次点击  
加入收藏 微博
1 回复  |  直到 2014-12-01 23:11:32
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传