go 的 interface
格式:
1) 定义接口
type interface_name interface {
func_name() value_type
}
2) 将类型与接口绑定, 即实现func_name
假设类型为 type_name
ex:
type type_name struct {
x,y float64
}
type type_name float64
实现func_name
func (v type_name)func_name() value_type {
return value_type(value)
}
3) 类型实现了接口定义的func_name 后, 即可通过接口来表达类型
var inter_value interface_name
var type_value type_name
inter_value = type_value
ex:
package main import ( "fmt" "math" ) type Abser interface { Abs() float64 } 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) } func main() { var a Abser f := MyFloat(-math.Sqrt2) v := Vertex{3,4} a = f fmt.Println(a) fmt.Println(a.Abs()) a = &v fmt.Println(a) fmt.Println(a.Abs()) }
其中 fmt 包,定义了很多内置的interface, 较为常用的:
type Stringer interface {
String() string
}
type error interface {
Error() string
}
package main import ( "fmt" "time" ) type MyError struct { When time.Time What string } func (e *MyError) Error() string { return fmt.Sprintf("at %v, %s", e.When, e.What) } func run() error { return &MyError{ time.Now(), "it didn't work", } } func main() { if err := run(); err != nil { fmt.Println(err) } }
package main import ( "fmt" "math" ) type ErrorSqrt float64 func (e ErrorSqrt) Error() string { //return fmt.Sprintf("cannot Sqrt negative number: %v", e) // 死循环, print e -> print Error() -> print e ... return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e)) } func Sqrt(x float64) (float64, error) { if x >= 0 { return math.Sqrt(x), nil } return 0, ErrorSqrt(x) } func main() { fmt.Println(Sqrt(2)) fmt.Println(Sqrt(-2)) }