go面向对象3
类型断言
.(type) 来实现 其中 type 对应的就是要断言的类型
接口类型断言
var num1 Number = 1
var num2 Number2 = &num1
if num3,ok := num2.(Number1);ok {
fmt.Println(num3.Equal(1))
}
结构体类型断言
type IAnimal interface {
GetName() string
Call() string
FavorFood() string
}
var animal = NewAnimal("蓝猫")
var pet = new Pet("蓝白")
var ianimal INamial = NewDog(&animal,pet)
if dog,ok := ianimal.(Dog); ok {
fmt.Println(dog.GetName())
}
基于反射动态断言类型
func myPrintf(args ...interface{}) {
for _,arg := range args {
swich reflect.TypeOf(arg).kind(){
case reflect.Int:
fmt.Println(arg,"is an int value")
case reflect.Array:
fmt.Println()
default :
}
}
}
如果要获取 ianimal的实际类型 可以使用 reflect.Typeof(ianimal) 获取
对于基本数据类型 比如int string bool 不必通过反射 直接使用variable.(type)
switch arg.(type)
空接口,反射 和泛型
interface{}
空接口和接口零值不是一个概念 前者是interface{} 后者是nil
空接口基本使用
空接口可以是指向任意类型变量
var v1 interface{} = 1
var v2 interface{} = true
复合类型
var v3 interface{} = struct{
id int,
name string
}{1,"fly"}
声明任意类型参数
func Printf(ftm string ,args ...interface{})
func Println(args ...interface{}) ...
func (p *pp) PrintArg(arg interface{},verb rune)
实现更灵活的类型断言
var animal = NewAnimal("蓝猫")
var pet = NewPet("蓝白猫")
var any interface{} = NewDog(&animal,pet)
if dog,ok := any.(Dog);ok {
}
反射
通过反射 可以在运行时动态的获取变量的类型和结构信息
非常典型的应用场景是ioc容器
reflect
reflect.TypeOf(dog)
reflect.TypeOf(&dog).Elem()
reflect.ValueOf(dog)
基于空接口和反射实现泛型
interface{} 本身可以表示任何类型 因此他是一个泛型
例子 自定义容器类型的实现来演示实现一个泛型
package main
import (
"fmt"
"reflect"
)
type Container struct {
s reflect.Value
}
func NewContainer( t reflect.Type,size int) *Container {
if size <= 0 {
szie = 64
}
return &Container{
s:reflect.MakeSlice(reflect.SliceOf(t) ,0 ,szie)
}
}
func (c *Container) Put(val interface{}) error {
if reflect.ValueOf(val).Type() != c.s.Type().Elem(){
return fmt.Errorf("put error :can not put a %T into a slice of %s",val,c.s.Type().Elem())
}
c.s = reflect.Append(c.s,reflect.ValueOf(val))
return nil
}
if err :=c.Put("s");err != nil{
panic(err)
}