接口
接口的定义
type Shape interfance {
Area() float64
Perimeter() float64
}
- interface,structs,methods 可以实现面向对象的特性
- interface是一系列方法的声明
接口有两个类型
- static 和 dynamic 类型
接口的零值是nil
package main
import "fmt"
type Shape interface{
Area() int
Perimeter() int
}
type Rect struct {
width int
length int
}
func (s Rect) Area() int {
return s.width * s.length
}
func (s Rect) Perimeter() int {
return 2 * (s.width + s.length)
}
func main() {
var r Shape = Rect{ 5.0, 4.0 }
fmt.Println(r.Area())
fmt.Println(r.Perimeter())
}
空接口
若在接口中没有声明方法,则说明该接口是空接口
_
内置fmt包中fmt接收的就是可变参数个数的函数,参数的类型是空接口
func Println(a ...interface{}) (n int, err error)
多接口
结构体可以继承多接口
package main
import "fmt"
type Shape interface {
Area() float64
}
type Object interface {
Volume() float64
}
type Cube struct {
side float64
}
func (c Cube) Area() float64 {
return c.side * c.side
}
func (c Cube) Volume() float64 {
return c.side * 2
}
func main() {
c := Cube{3}
fmt.Println(c.Area())
fmt.Println(c.Volume())
}
类型断言(Type assertion)
上面改的例子, 如果将
c := Cube{3}
改成
c := Cube{3}
var s Shape = c
后,调用 s.Volume() 方法就会出现异常
可以通过 类型声明 的特性改造上面的例子:
func main() {
var s shape = Cube(3)
c := s.(Cube)
fmt.Println(c.Area())
fmt.Println(c.Volume())
}
判断变量是否是混合类型
value, ok := i.(Type)
- 若ok=false, value是nil
Type Switch
- i.(type) 用来获取变量的类型
- i.(type) 用来转换变量的类型, 如i.(string)
package main
import (
"fmt"
"strings"
)
func explain(i interface{}) {
switch i.(type) {
case string:
fmt.Println("i store string ", strings.ToUpper(i.(string)))
case int:
fmt.Println("i store int ", i.(int))
default:
fmt.Println("i store something other ", i)
}
}
func main() {
explain("Hello world")
explain(53)
}
嵌套的接口
- 内嵌的接口就想内嵌的结构体一样,如果子接口的方法会自动上升到父接口
package main
type Shape interface {
Area() float64
}
type Object interface {
Volume() float64
}
type Material interface {
Shape
Ojbect
}
func main() {
c := Cube{3}
var m Material = c
var s Shape = c
var o Object = c
}
接口方法的接收者是指针还是普通类型值
- 如果实现接口的struct接收者是指针
package main
import "fmt"
type Shape interface {
Area() int
Perimeter() int
}
type Rect struct{
length int
width int
}
func (r *Rect) Area() int {
return r.length * r.width
}
func (r Rect) Perimeter() int {
return 2 * (r.length + r.width)
}
func main() {
r := Rect {5, 4}
var s Shape = &r // 由于方法接收者是指针
fmt.Println("Rect area is ", s.Area())
fmt.Println("Rect area is ", s.Perimeter())
}