golang接口基础用法
2010 年 11 月 2 日
定义
接口是一组包含方法名,参数,返回值的未具体实现方法的集合
基础用法如下:
package main import ( "fmt" ) type Schooler interface { Name() string Age() int Grade() int } type Student struct { name string age int grade int } func (s Student) Name() string { return s.name } func (s Student) Age() int { return s.age } func (s Student) Grade() int { return s.grade } func main() { var school Schooler student := Student{name: "Jack", age: 10, grade: 4} // 因为student实现了Schooler接口所以直接赋值没问题 school = student fmt.Printf("name:%v,age:%v,grade:%v\n", school.Name(), school.Age(), school.Grade()) // name:Jack,age:10,grade:4 }
空接口
空接口不包含任何方法,因此, 任意类型均实现了空接口
。
任意类型变量都可以赋值给空接口类型的变量,如下所示:
package main import ( "fmt" ) type Typer interface{} func main() { var tt Typer var a int var b float32 tt = a fmt.Printf("%T\n", tt) // int tt = b fmt.Printf("%T\n", tt) // float32 }
测试接口实现
测试变量是否实现了某个接口需要使用
x.(T)
的特定语法,如下所示:
package main import ( "fmt" ) type Schooler interface { Name() string Age() int } type Student struct { name string age int } type Teacher struct { name string age int } func (s Student) Name() string { return s.name } func (s Student) Age() int { return s.age } func (s Teacher) Name() string { return s.name } func CheckSchoolerImpliments(v interface{}) bool { if tmp, ok := v.(Schooler); ok { fmt.Printf("%T, %v", tmp, tmp) return true } return false } func main() { student := Student{name: "Jack", age: 10} teacher := Teacher{name: "Lucy", age: 26} fmt.Println(CheckSchoolerImpliments(student)) // main.Student, {Jack 10}true fmt.Println(CheckSchoolerImpliments(teacher)) // false }
类型断言
空接口可以存储任意类型,区分不同的类型常用两种方法, Comma-ok断言
和 switch判断
package main import ( "fmt" ) type Student struct { name string } func main() { var params = make([]interface{}, 3) fmt.Println(params) // [ ] params[0] = 18 params[1] = "hello" params[2] = Student{name: "Jack"} fmt.Println(params) // [18 hello {Jack}] for _, item := range params { if _, ok := item.(int); ok { fmt.Printf("%v's type is int\n", item) // 18's type is int } else if _, ok := item.(string); ok { fmt.Printf("%v's type is string\n", item) // hello's type is string } else if _, ok := item.(Student); ok { fmt.Printf("%v's type is struct\n", item) // {Jack}'s type is struct } } for _, item := range params { switch value := item.(type) { case int: fmt.Printf("%v's type is int\n", value) // 18's type is int case string: fmt.Printf("%v's type is string\n", item) // hello's type is string case Student: fmt.Printf("%v's type is struct\n", item) // {Jack}'s type is struct default: fmt.Printf("unknown type\n") } } }
接口零值
未赋值的接口类型为 nil
package main import ( "fmt" ) type Student interface { name() string } func main() { var s Student if s == nil { fmt.Println("s is nil") // s is nil } }
指针实现接口与值实现接口
package main import ( "fmt" ) type Schooler interface { Name() string Age() int } type Student struct { name string age int } type Teacher struct { name string age int } func (s Student) Name() string { return s.name } func (s Student) Age() int { return s.age } func (s *Teacher) Name() string { return s.name } func (s *Teacher) Age() int { return s.age } func main() { student := Student{name: "Jack", age: 10} teacher := Teacher{name: "Lucy", age: 26} var s Schooler s = student fmt.Printf("name:%v.age:%v\n", s.Name(), s.Age()) // name:Jack.age:10 // s = teacher // Teacher does not implement Schooler, *Teacher does s = &teacher fmt.Printf("name:%v.age:%v\n", s.Name(), s.Age()) //name:Lucy.age:26 }
接口嵌套
package main import ( "fmt" ) type Peopler interface { Name() string Age() int } type Schooler interface { Peopler Role() string } type Student struct { name string age int } type Teacher struct { name string age int } func (s Student) Name() string { return s.name } func (s Student) Age() int { return s.age } func (s Student) Role() string { return "Student" } func main() { student := Student{name: "Jack", age: 10} var p Peopler var s Schooler p = student fmt.Printf("name:%v, age:%v\n", p.Name(), p.Age()) // name:Jack.age:10 s = student fmt.Printf("name:%v, age:%v, role:%v\n", s.Name(), s.Age(), s.Role()) // name:Jack, age:10, role:Student }