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)

}

 

posted @ 2021-04-12 18:37  fly_fly_fly#  阅读(62)  评论(0编辑  收藏  举报