接口、反射(下)
接口
7. 接口嵌套
一个接口可以嵌套在另外的接口,如下所示:
type ReadWrite interface {
Read(b Buffer) bool
Write(b Buffer) bool
}
type Lock interface {
Lock()
Unlock()
}
type File interface {
ReadWrite
Lock
Close()
}
package main
import "fmt"
type Reader interface {
Read()
}
type Writer interface {
Write()
}
type ReadWriter interface {
Reader
Writer
}
type File struct {
}
func (f *File) Read() {
fmt.Println("read data")
}
func (f *File) Write() {
fmt.Println("write data")
}
func Test(rw ReadWriter) {
rw.Read()
rw.Write()
}
func main() {
var f *File
var b interface{}
b = f
//Test(&f)
v, ok := b.(ReadWriter)
fmt.Println(v, ok)
}
8. 类型断言,由于接口是一般类型,不知道具体类型,如果要转成具体类型
可以采用以下方法进行转换:
var t int
var x interface{}
x = t
y = x.(int) //转成int
var t int
var x interface{}
x = t
y, ok = x.(int) //转成int,带检查
练习,写一个函数判断传入参数的类型
func classifier(items ...interface{}) {
for i, x := range items {
switch x.(type) {
case bool: fmt.Printf(“param #%d is a bool\n”, i)
case float64: fmt.Printf(“param #%d is a float64\n”, i)
case int, int64: fmt.Printf(“param #%d is an int\n”, i)
case nil: fmt.Printf(“param #%d is nil\n”, i)
case string: fmt.Printf(“param #%d is a string\n”, i)
default: fmt.Printf(“param #%d’s type is unknown\n”, i)
}
}
类型断言,采用type switch方式
switch t := areaIntf.(type) {case *Square: fmt.Printf(“Type Square %T with value %v\n”, t, t)
case *Circle: fmt.Printf(“Type Circle %T with value %v\n”, t, t)
case float32: fmt.Printf(“Type float32 with value %v\n”, t)case nil: fmt.Println(“nil value: nothing to check?”)
default: fmt.Printf(“Unexpected type %T”, t)}
exp:
package main
import "fmt"
type Student struct {
Name string
Sex string
}
func Test(a interface{}) {
b, ok := a.(Student)
if ok == false {
fmt.Println("convert failed")
return
}
//b += 3
fmt.Println(b)
}
func just(items ...interface{}) {
for index, v := range items {
switch v.(type) {
case bool:
fmt.Printf("%d params is bool, value is %v\n", index, v)
case int, int64, int32:
fmt.Printf("%d params is int, value is %v\n", index, v)
case float32, float64:
fmt.Printf("%d params is float, value is %v\n", index, v)
case string:
fmt.Printf("%d params is string, value is %v\n", index, v)
case Student:
fmt.Printf("%d params student, value is %v\n", index, v)
case *Student:
fmt.Printf("%d params *student, value is %v\n", index, v)
}
}
}
func main() {
var b Student = Student{
Name: "stu01",
Sex: "female",
}
Test(b)
just(28, 8.2, "this is a test", b, &b)
}
11. 空接口,Interface{}
空接口没有任何方法,所以所有类型都实现了空接口。
var a int
var b interface{}
b = a
12. 判断一个变量是否实现了指定接口
type Stringer interface {
String() string
}
var v MyStruct
if sv, ok := v.(Stringer); ok {
fmt.Printf(“v implements String(): %s\n”, sv.String());
}
反射
1、反射:可以在运行时动态获取变量的相关信息
Import (“reflect”)
a. reflect.TypeOf,获取变量的类型,返回reflect.Type类型
b. reflect.ValueOf,获取变量的值,返回reflect.Value类型
c. reflect.Value.Kind,获取变量的类别,返回一个常量
d. reflect.Value.Interface(),转换成interface{}类型
2. reflect.Value.Kind()方法返回的常量
const (
Invalid Kind = iota
Bool
Int
Int8
Int16
Int32
Int64
Uint
Uint8
Uint16
Uint32
Uint64
Uintptr
Float32
Float64
Complex64
Complex128
Array
Chan
Func
Interface
Map
Ptr
Slice
String
Struct
UnsafePointer
)
3. 练习:
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
v := reflect.ValueOf(x)
fmt.Println("value:", v)
fmt.Println("type:", v.Type())
fmt.Println("kind:", v.Kind())
fmt.Println("value:", v.Float())
fmt.Println(v.Interface())
fmt.Printf("value is %5.2e\n", v.Interface())
y := v.Interface().(float64)
fmt.Println(y)
}
4. 获取变量的值:
- reflect.ValueOf(x).Float()
- reflect.ValueOf(x).Int()
- reflect.ValueOf(x).String()
- reflect.ValueOf(x).Bool()
5. 通过反射的来改变变量的值
reflect.Value.SetXX相关方法,比如:
- reflect.Value.SetFloat(),设置浮点数
- reflect.Value.SetInt(),设置整数
- reflect.Value.SetString(),设置字符串
package main
import (
"fmt"
"reflect"
)
func main() {
var a float64
fv := reflect.ValueOf(&a)
fv.Elem().SetFloat(3.3)
fmt.Printf("%v\n", a)
}
其中fv.Elem()用来获取指针指向的变量,相当于:
var a *int;
*a = 100
9. 用反射操作结构体
a. reflect.Value.NumField()获取结构体中字段的个数
b. reflect.Value.Method(n).Call来调用结构体中的方法
10. 练习
package main
import (
"fmt"
“reflect"
)
type NotknownType struct {
s1 string
s2 string
s3 string
}
func (n NotknownType) String() string {
return n.s1 + "-" + n.s2 + "-" + n.s3
}
var secret interface{} = NotknownType{"Ada", "Go", "Oberon"}
func main() {
value := reflect.ValueOf(secret) // <main.NotknownType Value>
typ := reflect.TypeOf(secret) // main.NotknownType
fmt.Println(typ)
knd := value.Kind() // struct
fmt.Println(knd)
for i := 0; i < value.NumField(); i++ {
fmt.Printf("Field %d: %v\n", i, value.Field(i))
//value.Field(i).SetString("C#")
}
results := value.Method(0).Call(nil)
fmt.Println(results) // [Ada - Go - Oberon]
}
10. 练习,通过反射操作结构体
package main
import (
"fmt"
“reflect"
)
type NotknownType struct {
s1 string
s2 string
s3 string
}
func (n NotknownType) String() string {
return n.s1 + "-" + n.s2 + "-" + n.s3
}
var secret interface{} = NotknownType{"Ada", "Go", "Oberon"}
func main() {
value := reflect.ValueOf(secret) // <main.NotknownType Value>
typ := reflect.TypeOf(secret) // main.NotknownType
fmt.Println(typ)
knd := value.Kind() // struct
fmt.Println(knd)
for i := 0; i < value.NumField(); i++ {
fmt.Printf("Field %d: %v\n", i, value.Field(i))
//value.Field(i).SetString("C#")
}
results := value.Method(0).Call(nil)
fmt.Println(results) // [Ada - Go - Oberon]
}
10. 练习2,通过反射修改结构体
package main
import (
"fmt"
"reflect"
)
type T struct {
A int
B string
}
func main() {
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}
s.Field(0).SetInt(77)
s.Field(1).SetString("Sunset Strip")
fmt.Println("t is now", t)
}
exp:
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type Student struct {
Name string `json:"student_name"`
Age int
Score float32
Sex string
}
func (s Student) Print() {
fmt.Println("---start----")
fmt.Println(s)
fmt.Println("---end----")
}
func (s Student) Set(name string, age int, score float32, sex string) {
s.Name = name
s.Age = age
s.Score = score
s.Sex = sex
}
func TestStruct(a interface{}) {
tye := reflect.TypeOf(a)
val := reflect.ValueOf(a)
kd := val.Kind()
if kd != reflect.Ptr && val.Elem().Kind() == reflect.Struct {
fmt.Println("expect struct")
return
}
num := val.Elem().NumField()
val.Elem().Field(0).SetString("stu1000")
for i := 0; i < num; i++ {
fmt.Printf("%d %v\n", i, val.Elem().Field(i).Kind())
}
fmt.Printf("struct has %d fields\n", num)
tag := tye.Elem().Field(0).Tag.Get("json")
fmt.Printf("tag=%s\n", tag)
numOfMethod := val.Elem().NumMethod()
fmt.Printf("struct has %d methods\n", numOfMethod)
var params []reflect.Value
val.Elem().Method(0).Call(params)
}
func main() {
var a Student = Student{
Name: "stu01",
Age: 18,
Score: 92.8,
}
result, _ := json.Marshal(a)
fmt.Println("json result:", string(result))
TestStruct(&a)
fmt.Println(a)
}

浙公网安备 33010602011771号