一、interface简介
interface(接口)是golang最重要的特性之一,Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能包含任何变量。
简单的说:
- interface是方法的集合
- interface是一种类型,并且是指针类型
- interface的更重要的作用在于多态实现
interface定义
type 接口名称
interface使用
- 接口的使用不仅仅针对结构体,自定义类型、变量等等都可以实现接口。
- 如果一个接口没有任何方法,我们称为空接口,由于空接口没有方法,所以任何类型都实现了空接口。
- 要实现一个接口,必须实现该接口里面的所有方法。
import <span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #008000;">//<span style="color: #008000;">定义接口
type Skills <span style="color: #0000ff;">interface<span style="color: #000000;"> {
Running()
Getname() <span style="color: #0000ff;">string<span style="color: #000000;">
}
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string<span style="color: #000000;">
Age <span style="color: #0000ff;">int<span style="color: #000000;">
}
<span style="color: #008000;">//<span style="color: #008000;"> 实现接口
func (p Student) Getname() <span style="color: #0000ff;">string{ <span style="color: #008000;">//<span style="color: #008000;">实现Getname方法
<span style="color: #000000;"> fmt.Println(p.Name )
<span style="color: #0000ff;">return<span style="color: #000000;"> p.Name
}
func (p Student) Running() { <span style="color: #008000;">//<span style="color: #008000;"> 实现 Running方法
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">%s running<span style="color: #800000;">"<span style="color: #000000;">,p.Name)
}
func main() {
<span style="color: #0000ff;">var<span style="color: #000000;"> skill Skills
<span style="color: #0000ff;">var<span style="color: #000000;"> stu1 Student
stu1.Name = <span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">"<span style="color: #000000;">
stu1.Age = <span style="color: #800080;">22<span style="color: #000000;">
skill =<span style="color: #000000;"> stu1
skill.Running() <span style="color: #008000;">//<span style="color: #008000;">调用接口
<span style="color: #000000;">}
<span style="color: #008000;">//<span style="color: #008000;">wd running
多态
上面提到了,go语言中interface是实现多态的一种形式,所谓多态,就是一种事物的多种形态,与python中类的多态是一致的。
同一个interface,不同的类型实现,都可以进行调用,它们都按照统一接口进行操作。
在上面的示例中,我们增加一个Teacher结构体,同样实现接口进行说明:
import <span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
type Skills <span style="color: #0000ff;">interface<span style="color: #000000;"> {
Running()
Getname() <span style="color: #0000ff;">string<span style="color: #000000;">
}
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string<span style="color: #000000;">
Age <span style="color: #0000ff;">int<span style="color: #000000;">
}
type Teacher <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string<span style="color: #000000;">
Salary <span style="color: #0000ff;">int<span style="color: #000000;">
}
func (p Student) Getname() <span style="color: #0000ff;">string{ <span style="color: #008000;">//<span style="color: #008000;">实现Getname方法
<span style="color: #000000;"> fmt.Println(p.Name )
<span style="color: #0000ff;">return<span style="color: #000000;"> p.Name
}
func (p Student) Running() { <span style="color: #008000;">//<span style="color: #008000;"> 实现 Running方法
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">%s running<span style="color: #800000;">"<span style="color: #000000;">,p.Name)
}
func (p Teacher) Getname() <span style="color: #0000ff;">string{ <span style="color: #008000;">//<span style="color: #008000;">实现Getname方法
<span style="color: #000000;"> fmt.Println(p.Name )
<span style="color: #0000ff;">return<span style="color: #000000;"> p.Name
}
func (p Teacher) Running() { <span style="color: #008000;">//<span style="color: #008000;"> 实现 Running方法
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">n%s running<span style="color: #800000;">"<span style="color: #000000;">,p.Name)
}
func main() {
<span style="color: #0000ff;">var<span style="color: #000000;"> skill Skills
<span style="color: #0000ff;">var<span style="color: #000000;"> stu1 Student
<span style="color: #0000ff;">var<span style="color: #000000;"> t1 Teacher
t1.Name = <span style="color: #800000;">"<span style="color: #800000;">wang<span style="color: #800000;">"<span style="color: #000000;">
stu1.Name = <span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">"<span style="color: #000000;">
stu1.Age = <span style="color: #800080;">22<span style="color: #000000;">
skill =<span style="color: #000000;"> stu1
skill.Running()
skill =<span style="color: #000000;"> t1
t1.Running()
}
<span style="color: #008000;">//<span style="color: #008000;">wd running
<span style="color: #008000;">//<span style="color: #008000;">wang running
接口嵌套
go语言中的接口可以嵌套,可以理解我继承,子接口拥有父接口的所有方法,并且想要使用该子接口的话,必须将父接口和子接口的所有方法都实现。
type Skills }
type Test <span style="color: #0000ff;">interface<span style="color: #000000;"> {
sleeping()
Skills <span style="color: #008000;">//<span style="color: #008000;">继承Skills
}
类型转换
由于接口是一般类型,当我们使用接口时候可能不知道它是那个类型实现的,基本数据类型我们有对应的方法进行类型转换,当然接口类型也有类型转换。
当然我们也可以用这个方式来进行类型的判断。
转换方式:
s
x x =<span style="color: #000000;"> s
y,ok := x.(<span style="color: #0000ff;">int) <span style="color: #008000;">//<span style="color: #008000;">将interface 转为int,ok可省略 但是省略以后转换失败会报错,true转换成功,false转换失败,并采用默认值
示例:
import <span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
func main() {
<span style="color: #0000ff;">var x <span style="color: #0000ff;">interface<span style="color: #000000;">{}
s :</span>= <span style="color: #800000;">"</span><span style="color: #800000;">WD</span><span style="color: #800000;">"</span><span style="color: #000000;">
x </span>=<span style="color: #000000;"> s
y,ok :</span>= x.(<span style="color: #0000ff;">int</span><span style="color: #000000;">)
z,ok1 :</span>= x.(<span style="color: #0000ff;">string</span><span style="color: #000000;">)
fmt.Println(y,ok)
fmt.Println(z,ok1)
}
<span style="color: #008000;">//<span style="color: #008000;">0 false
<span style="color: #008000;">//<span style="color: #008000;">WD true
判断类型示例:
import <span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string<span style="color: #000000;">
}
func TestType(items ...<span style="color: #0000ff;">interface<span style="color: #000000;">{}) {
<span style="color: #0000ff;">for k,v :=<span style="color: #000000;"> range items {
<span style="color: #0000ff;">switch<span style="color: #000000;"> v.(type) {
<span style="color: #0000ff;">case <span style="color: #0000ff;">string<span style="color: #000000;">:
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">type is string,%d[%v]n<span style="color: #800000;">"<span style="color: #000000;">,k,v)
<span style="color: #0000ff;">case <span style="color: #0000ff;">bool<span style="color: #000000;">:
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">type is bool,v)
<span style="color: #0000ff;">case <span style="color: #0000ff;">int<span style="color: #000000;">:
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">type is int,v)
<span style="color: #0000ff;">case<span style="color: #000000;"> float32,float64:
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">type is float,v)
<span style="color: #0000ff;">case<span style="color: #000000;"> Student:
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">type is Student,v)
<span style="color: #0000ff;">case *<span style="color: #000000;">Student:
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">type is Student,%d[%p]n<span style="color: #800000;">"<span style="color: #000000;">,v)
}
}
}
func main() {
<span style="color: #0000ff;">var<span style="color: #000000;"> stu Student
TestType(<span style="color: #800000;">"<span style="color: #800000;">WD<span style="color: #800000;">",<span style="color: #800080;">100,stu,<span style="color: #800080;">3.3<span style="color: #000000;">)
}
<span style="color: #008000;">//<span style="color: #008000;">type is string,0[WD]
<span style="color: #008000;">//<span style="color: #008000;">type is int,1[100]
<span style="color: #008000;">//<span style="color: #008000;">type is Student,2[{}]
<span style="color: #008000;">//<span style="color: #008000;">type is float,3[3.3]
二、反射reflect
反射是程序执行时检查其所拥有的结构。尤其是类型的一种能力。这是元编程的一种形式。它同一时候也是造成混淆的重要来源。
每一个语言的反射模型都不同(同一时候很多语言根本不支持反射,python通过hasattr方法实现)
go语言中的反射通过refect包实现,reflect包实现了运行时反射,允许程序操作任意类型的对象。
在介绍反射之前先说明下reflect包中的两个数据类Type和Value。
Type
Type:Type类型用来表示一个go类型。
不是所有go类型的Type值都能使用所有方法。请参见每个方法的文档获取使用限制。在调用有分类限定的方法时,应先使用Kind方法获知类型的分类。调用该分类不支持的方法会导致运行时的panic。
获取Type对象的方法:
func TypeOf(i {}) Type
示例:
import (
<span style="color: #800000;">"<span style="color: #800000;">reflect<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
str := <span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">"<span style="color: #000000;">
res_type :=<span style="color: #000000;"> reflect.TypeOf(str)
fmt.Println(res_type) <span style="color: #008000;">//<span style="color: #008000;">string
}
reflect.Type中方法
通用方法:
*rtype) String()
*rtype) Name()
*rtype) PkgPath()
*rtype) Kind() reflect.Kind
*rtype) Size() uintptr
*rtype) Align()
*rtype) FieldAlign()
*rtype) NumMethod()
*rtype) Method() reflect.Method
*rtype) MethodByName() (reflect.Method,)
*rtype) Implements(u reflect.Type)
*rtype) ConvertibleTo(u reflect.Type)
*rtype) AssignableTo(u reflect.Type)
*rtype) Comparable()
(t *rtype) () reflect.Type
示例:
import (
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">reflect<span style="color: #800000;">"<span style="color: #000000;">
)
type Skills <span style="color: #0000ff;">interface<span style="color: #000000;"> {
reading()
running()
}
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string<span style="color: #000000;">
Age <span style="color: #0000ff;">int<span style="color: #000000;">
}
func (self Student) runing(){
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">%s is runningn<span style="color: #800000;">"<span style="color: #000000;">,self.Name)
}
func (self Student) reading(){
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">%s is readingn<span style="color: #800000;">"<span style="color: #000000;">,self.Name)
}
func main() {
stu1 := Student{Name:<span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">",Age:<span style="color: #800080;">22<span style="color: #000000;">}
inf := <span style="color: #0000ff;">new<span style="color: #000000;">(Skills)
stu_type :=<span style="color: #000000;"> reflect.TypeOf(stu1)
inf_type := reflect.TypeOf(inf).Elem() <span style="color: #008000;">//<span style="color: #008000;"> 特别说明,引用类型需要用Elem()获取指针所指的对象类型
fmt.Println(stu_type.String()) <span style="color: #008000;">//<span style="color: #008000;">main.Student
fmt.Println(stu_type.Name()) <span style="color: #008000;">//<span style="color: #008000;">Student
fmt.Println(stu_type.PkgPath()) <span style="color: #008000;">//<span style="color: #008000;">main
fmt.Println(stu_type.Kind()) <span style="color: #008000;">//<span style="color: #008000;">struct
fmt.Println(stu_type.Size()) <span style="color: #008000;">//<span style="color: #008000;">24
fmt.Println(inf_type.NumMethod()) <span style="color: #008000;">//<span style="color: #008000;">2
fmt.Println(inf_type.Method(<span style="color: #800080;">0),inf_type.Method(<span style="color: #800080;">0).Name) <span style="color: #008000;">//<span style="color: #008000;"> {reading main func() 0} reading
fmt.Println(inf_type.MethodByName(<span style="color: #800000;">"<span style="color: #800000;">reading<span style="color: #800000;">")) <span style="color: #008000;">//<span style="color: #008000;">{reading main func() 0} true
<span style="color: #000000;">
}
其他方法:
*rtype) Bits()
<span style="color: #008000;">// <span style="color: #008000;"> 数组
<span style="color: #000000;">
func (t *rtype) Len() <span style="color: #0000ff;">int <span style="color: #008000;">//<span style="color: #008000;"> 获取数组的元素个数
<span style="color: #008000;">//<span style="color: #008000;"> 映射
<span style="color: #000000;">
func (t *rtype) Key() reflect.Type <span style="color: #008000;">//<span style="color: #008000;"> 获取映射的键类型
<span style="color: #008000;">//<span style="color: #008000;"> 通道
<span style="color: #000000;">
func (t *rtype) ChanDir() reflect.ChanDir <span style="color: #008000;">//<span style="color: #008000;"> 获取通道的方向
<span style="color: #008000;">//<span style="color: #008000;"> 结构体
<span style="color: #000000;">
func (t rtype) NumField() <span style="color: #0000ff;">int <span style="color: #008000;">//<span style="color: #008000;"> 获取字段数量
<span style="color: #000000;">
func (t rtype) Field(<span style="color: #0000ff;">int) reflect.StructField <span style="color: #008000;">//<span style="color: #008000;"> 根据索引获取字段
<span style="color: #000000;">
func (t rtype) FieldByName(<span style="color: #0000ff;">string) (reflect.StructField,<span style="color: #0000ff;">bool) <span style="color: #008000;">//<span style="color: #008000;"> 根据名称获取字段
<span style="color: #000000;">
func (t rtype) FieldByNameFunc(match func(<span style="color: #0000ff;">string) <span style="color: #0000ff;">bool) (reflect.StructField,<span style="color: #0000ff;">bool) <span style="color: #008000;">//<span style="color: #008000;"> 根据指定的匹配函数 math 获取字段
<span style="color: #000000;">
func (t *rtype) FieldByIndex(index []<span style="color: #0000ff;">int) reflect.StructField <span style="color: #008000;">//<span style="color: #008000;"> 根据索引链获取嵌套字段
<span style="color: #008000;">//<span style="color: #008000;"> 函数
<span style="color: #000000;">
func (t rtype) NumIn() <span style="color: #0000ff;">int <span style="color: #008000;">//<span style="color: #008000;"> 获取函数的参数数量
<span style="color: #000000;">
func (t rtype) In(<span style="color: #0000ff;">int) reflect.Type <span style="color: #008000;">//<span style="color: #008000;"> 根据索引获取函数的参数信息
<span style="color: #000000;">
func (t rtype) NumOut() <span style="color: #0000ff;">int <span style="color: #008000;">//<span style="color: #008000;"> 获取函数的返回值数量
<span style="color: #000000;">
func (t rtype) Out(<span style="color: #0000ff;">int) reflect.Type <span style="color: #008000;">//<span style="color: #008000;"> 根据索引获取函数的返回值信息
<span style="color: #000000;">
func (t *rtype) IsVariadic() <span style="color: #0000ff;">bool <span style="color: #008000;">//<span style="color: #008000;"> 判断函数是否具有可变参数。
<span style="color: #008000;">//<span style="color: #008000;"> 如果有可变参数,则 t.In(t.NumIn()-1) 将返回一个切片。
示例:
import (
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">reflect<span style="color: #800000;">"<span style="color: #000000;">
)
type Skills <span style="color: #0000ff;">interface<span style="color: #000000;"> {
reading()
running()
}
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string<span style="color: #000000;">
Age <span style="color: #0000ff;">int<span style="color: #000000;">
}
func (self Student) runing(){
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">%s is runningn<span style="color: #800000;">"<span style="color: #000000;">,Age:<span style="color: #800080;">22<span style="color: #000000;">}
stu_type :=<span style="color: #000000;"> reflect.TypeOf(stu1)
fmt.Println(stu_type.NumField()) <span style="color: #008000;">//<span style="color: #008000;">2
fmt.Println(stu_type.Field(<span style="color: #800080;">0)) <span style="color: #008000;">//<span style="color: #008000;">{Name string 0 [0] false}
fmt.Println(stu_type.FieldByName(<span style="color: #800000;">"<span style="color: #800000;">Age<span style="color: #800000;">")) <span style="color: #008000;">//<span style="color: #008000;">{{Age int 16 [1] false} true
}
Value
不是所有go类型值的Value表示都能使用所有方法。请参见每个方法的文档获取使用限制。在调用有分类限定的方法时,应先使用Kind方法获知该值的分类。调用该分类不支持的方法会导致运行时的panic。
Value为go值提供了反射接口,获取Value对象方法:
func ValueOf(i {}) Value
示例:
str := =
reflect.Value方法
注意:以下所有方法中的v是reflect.Value返回的值。
reflect.Value.Kind():获取变量类别,返回常量
=
import (
<span style="color: #800000;">"<span style="color: #800000;">reflect<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
str := <span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">"<span style="color: #000000;">
val :=<span style="color: #000000;"> reflect.ValueOf(str).Kind()
fmt.Println(val)<span style="color: #008000;">//<span style="color: #008000;">string
}
用于获取值方法:
func (v Value) Int() int64
) reflect.Value
) reflect.Value
) reflect.Value
设置值方法:
func (v Value) SetInt(x int64)
)
)
)
)
)
其他方法:
func (v Value) NumField()
) reflect.Value
) reflect.Value
) reflect.Value
) ) Value <span style="color: #008000;">########通道相关:
func (v Value) Send(x reflect.Value)<span style="color: #008000;">//<span style="color: #008000;"> 发送数据(会阻塞),v 值必须是可写通道。
<span style="color: #000000;">
func (v Value) Recv() (x reflect.Value,ok <span style="color: #0000ff;">bool) <span style="color: #008000;">//<span style="color: #008000;"> 接收数据(会阻塞),v 值必须是可读通道。
<span style="color: #000000;">
func (v Value) TrySend(x reflect.Value) <span style="color: #0000ff;">bool <span style="color: #008000;">//<span style="color: #008000;"> 尝试发送数据(不会阻塞),v 值必须是可写通道。
<span style="color: #000000;">
func (v Value) TryRecv() (x reflect.Value,ok <span style="color: #0000ff;">bool) <span style="color: #008000;">//<span style="color: #008000;"> 尝试接收数据(不会阻塞),v 值必须是可读通道。
<span style="color: #000000;">
func (v Value) Close() <span style="color: #008000;">//<span style="color: #008000;"> 关闭通道
<span style="color: #008000;">########函数相关
func (v Value) Call(<span style="color: #0000ff;">in []Value) (r []Value) <span style="color: #008000;">//<span style="color: #008000;"> 通过参数列表 in 调用 v 值所代表的函数(或方法)。函数的返回值存入 r 中返回。
<span style="color: #008000;">//<span style="color: #008000;"> 要传入多少参数就在 in 中存入多少元素。
<span style="color: #008000;">//<span style="color: #008000;"> Call 即可以调用定参函数(参数数量固定),也可以调用变参函数(参数数量可变)。
<span style="color: #000000;">
func (v Value) CallSlice(<span style="color: #0000ff;">in []Value) []Value <span style="color: #008000;">//<span style="color: #008000;"> 调用变参函数
示例一:获取和设置普通类型的值
import (
<span style="color: #800000;">"<span style="color: #800000;">reflect<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
str := <span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">"<span style="color: #000000;">
age := <span style="color: #800080;">11<span style="color: #000000;">
fmt.Println(reflect.ValueOf(str).String()) <span style="color: #008000;">//<span style="color: #008000;">获取str的值,结果wd
fmt.Println(reflect.ValueOf(age).Int()) <span style="color: #008000;">//<span style="color: #008000;">获取age的值,结果age
str2 := reflect.ValueOf(&str) <span style="color: #008000;">//<span style="color: #008000;">获取Value类型
str2.Elem().SetString(<span style="color: #800000;">"<span style="color: #800000;">jack<span style="color: #800000;">") <span style="color: #008000;">//<span style="color: #008000;">设置值
fmt.Println(str2.Elem(),age) <span style="color: #008000;">//<span style="color: #008000;">jack 11
}
示例二:简单结构体操作
import (
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">reflect<span style="color: #800000;">"<span style="color: #000000;">
)
type Skills <span style="color: #0000ff;">interface<span style="color: #000000;"> {
reading()
running()
}
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string<span style="color: #000000;">
Age <span style="color: #0000ff;">int<span style="color: #000000;">
}
func (self Student) runing(){
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">%s is runningn<span style="color: #800000;">"<span style="color: #000000;">,Age:<span style="color: #800080;">22<span style="color: #000000;">}
stu_val := reflect.ValueOf(stu1) <span style="color: #008000;">//<span style="color: #008000;">获取Value类型
fmt.Println(stu_val.NumField()) <span style="color: #008000;">//<span style="color: #008000;">2
fmt.Println(stu_val.Field(<span style="color: #800080;">0),stu_val.Field(<span style="color: #800080;">1)) <span style="color: #008000;">//<span style="color: #008000;">wd 22
fmt.Println(stu_val.FieldByName(<span style="color: #800000;">"<span style="color: #800000;">Age<span style="color: #800000;">")) <span style="color: #008000;">//<span style="color: #008000;">22
stu_val2 := reflect.ValueOf(&<span style="color: #000000;">stu1).Elem()
stu_val2.FieldByName(<span style="color: #800000;">"<span style="color: #800000;">Age<span style="color: #800000;">").SetInt(<span style="color: #800080;">33) <span style="color: #008000;">//<span style="color: #008000;">设置字段值 ,结果33
<span style="color: #000000;"> fmt.Println(stu1.Age)
}
示例三:通过反射调用结构体中的方法,通过reflect.Value.Method(i int).Call()或者reflect.Value.MethodByName(name string).Call()实现
import (
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">reflect<span style="color: #800000;">"<span style="color: #000000;">
)
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string<span style="color: #000000;">
Age <span style="color: #0000ff;">int<span style="color: #000000;">
}
func (<span style="color: #0000ff;">this *Student) SetName(name <span style="color: #0000ff;">string<span style="color: #000000;">) {
<span style="color: #0000ff;">this.Name =<span style="color: #000000;"> name
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">set name %sn<span style="color: #800000;">",<span style="color: #0000ff;">this<span style="color: #000000;">.Name )
}
func (<span style="color: #0000ff;">this *Student) SetAge(age <span style="color: #0000ff;">int<span style="color: #000000;">) {
<span style="color: #0000ff;">this.Age =<span style="color: #000000;"> age
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">set age %dn<span style="color: #800000;">"<span style="color: #000000;">,age )
}
func (<span style="color: #0000ff;">this *Student) String() <span style="color: #0000ff;">string<span style="color: #000000;"> {
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">this is %sn<span style="color: #800000;">",<span style="color: #0000ff;">this<span style="color: #000000;">.Name)
<span style="color: #0000ff;">return <span style="color: #0000ff;">this<span style="color: #000000;">.Name
}
func main() {
stu1 := &Student{Name:<span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">",Age:<span style="color: #800080;">22<span style="color: #000000;">}
val := reflect.ValueOf(stu1) <span style="color: #008000;">//<span style="color: #008000;">获取Value类型,也可以使用reflect.ValueOf(&stu1).Elem()
val.MethodByName(<span style="color: #800000;">"<span style="color: #800000;">String<span style="color: #800000;">").Call(nil) <span style="color: #008000;">//<span style="color: #008000;">调用String方法
<span style="color: #0000ff;">params</span> := make([]reflect.Value,<span style="color: #800080;">1</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">params</span>[<span style="color: #800080;">0</span>] = reflect.ValueOf(<span style="color: #800080;">18</span><span style="color: #000000;">)
val.MethodByName(</span><span style="color: #800000;">"</span><span style="color: #800000;">SetAge</span><span style="color: #800000;">"</span>).Call(<span style="color: #0000ff;">params</span>) <span style="color: #008000;">//</span><span style="color: #008000;">通过名称调用方法</span>
<span style="color: #0000ff;">params</span>[<span style="color: #800080;">0</span>] = reflect.ValueOf(<span style="color: #800000;">"</span><span style="color: #800000;">jack</span><span style="color: #800000;">"</span><span style="color: #000000;">)
val.Method(</span><span style="color: #800080;">1</span>).Call(<span style="color: #0000ff;">params</span>) <span style="color: #008000;">//</span><span style="color: #008000;">通过方法索引调用</span>
<span style="color: #000000;">
fmt.Println(stu1.Name,stu1.Age)
}
<span style="color: #008000;">//<span style="color: #008000;">this is wd
<span style="color: #008000;">//<span style="color: #008000;">set age 18
<span style="color: #008000;">//<span style="color: #008000;">set name jack
<span style="color: #008000;">//<span style="color: #008000;">jack 18
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|