多态

34 阅读1分钟

代码演示

package interface_test

import (
    "fmt"
    "testing"
)

type Code string

type Programmer interface {
    WriteCode() Code
}

type GoProgrammer struct{}

func (g *GoProgrammer) WriteCode() Code {
    return Code(`fmt.Println("Hello world")`)
}

type PythonProgrammer struct{}

func (p *PythonProgrammer) WriteCode() Code {
    return Code(`print("Hello world")`)
}

func writeFirstProgram(p Programmer) {
    fmt.Printf("%T %v\n", p, p.WriteCode)
}

func TestPolymorphism(t *testing.T) {
    goProg := new(GoProgrammer)
    pythonProg := new(PythonProgrammer)
    writeFirstProgram(goProg)
    writeFirstProgram(pythonProg)
}

空接口与断言

  1. 空接口可以表示任何类型
  2. 通过单元来将空接口转换成指定类型
func DoSomethingWithIf(p interface{}) {
   if i, ok := p.(int); ok {
      fmt.Println("Integer", i)
      return
   }
   if i, ok := p.(string); ok {
      fmt.Println("Integer", i)
      return
   }
   fmt.Println("Unknown Type")
}

func DoSomethingWithSwitch(p interface{}) {
   switch v := p.(type) {
   case int:
      fmt.Println("Integer", v)
   case string:
      fmt.Println("String", v)
   default:
      fmt.Println("Unknown Type")
   }
}
func TestEmptyInterfaceAssertion(t *testing.T) {
   DoSomethingWithIf(10)
}

Go接口最佳实践

  1. 倾向于使用小的接口定义,很多接口只包含一个方法
type Reader interface {
    Read(p []byte) (n int, err error)
}
type Writeer interface {
    Write(p []byte) (n int, err error)
}
  1. 较大的接口定义,可以有多个小接口定义组合而成
type ReadWriter interface {
    Reader
    Writer
}
  1. 只依赖于必要功能的最小接口
func StoreData(reader Reader) error {
    ...
}
  1. 接口定义:在Go语言中,定义接口名的时候一般都是以er结尾