断言
把一个接口类型指定为它的原始类型
type User struct {
Username string
Email string
}
type Admin struct {
User
}
func (u User) sayHello() {
fmt.Println("Hello", u.Username)
}
func check(v interface{}) {
// v 就是断言传进来的类型是 User
v.(User).sayHello()
}
func checkEnhanced(v interface{}) {
// v 就是断言传进来的类型是 User
switch v.(type) {
case User:
fmt.Println("User")
v.(User).sayHello()
case Admin:
fmt.Println("Admin")
default:
fmt.Println("Unknown")
}
}
func main() {
u := User{
Username: "Rizky",
Email: "",
}
//check(u)
checkEnhanced(u)
}
反射
官方说法:在编译时不知道类型的情况下,可更新变量、运行时查看值、调用方法以及直接对他们的布局进行操作的机制,称为反射。
通俗说法:可以知道变量原始数据类型和内容、方法等,并且可以进行一定的操作
为什么要用反射?
接受到类型不固定的数据时,需要写太多 switch case 断言
此时代码不灵活,通用性差
反射可以无视类型,直接操作数据
反射的几个方法的
reflect.TypeOf() // 获取类型
reflect.ValueOf() // 获取值
reflect.ValueOf().Kind() // 获取类型
reflect.ValueOf().Interface() // 获取值
通过反射调用方法文章来源:https://www.toymoban.com/news/detail-583604.html
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func (p Person) SayHello() {
fmt.Println("Hello, my name is", p.Name)
}
func testReflectMethod(p interface{}) {
//p := Person{Name: "Alice", Age: 30}
// 使用反射调用方法
reflect.ValueOf(p).MethodByName("SayHello").Call([]reflect.Value{})
}
func main() {
p := Person{Name: "Alice", Age: 30}
// 使用反射调用方法
//methodValue := reflect.ValueOf(p).MethodByName("SayHello")
//if methodValue.IsValid() {
// methodValue.Call([]reflect.Value{})
//} else {
// fmt.Println("Method not found")
//}
testReflectMethod(p)
}
通过反射获取值,修改值文章来源地址https://www.toymoban.com/news/detail-583604.html
package main
import (
"fmt"
"reflect"
)
type User struct {
Username string
Email string
}
type Admin struct {
Title string
User
}
func (u User) sayHello() {
fmt.Println("Hello", u.Username)
}
func check(inter interface{}) {
// v 就是断言传进来的类型是 User
t := reflect.TypeOf(inter)
v := reflect.ValueOf(inter)
fmt.Println(t, v)
// 调用方法
// 根据字段名获取字段值
u := v.FieldByName("User").FieldByName("Email")
fmt.Println("value of u", u)
// 根据索引获取字段值
fmt.Println(v.FieldByIndex([]int{0}))
fmt.Println(v.FieldByIndex([]int{1}))
// 取索引 1 里面的 索引 1 的值
fmt.Println("{1, 1}", v.FieldByIndex([]int{1, 1}))
for i := 0; i < t.NumField(); i++ {
fmt.Println(t.Field(i).Name, v.Field(i).Interface())
}
kind := t.Kind()
// 判断是否是结构体
if kind == reflect.Struct {
fmt.Println("kind is struct")
}
}
func changeValue(inter interface{}) {
v := reflect.ValueOf(inter)
e := v.Elem()
e.FieldByName("Username").SetString("Rizky000")
fmt.Println(inter)
}
func checkEnhanced(v interface{}) {
// v 就是断言传进来的类型是 User
switch v.(type) {
case User:
fmt.Println("User")
v.(User).sayHello()
case Admin:
fmt.Println("Admin")
default:
fmt.Println("Unknown")
}
}
func main() {
u := User{
Username: "Rizky",
Email: "@eyou.com",
}
//admin := Admin{
// Title: "Admin",
// User: u,
//}
//check(admin)
//checkEnhanced(u)
//changeValue(&u)
//check(u)
//fmt.Println(u)
}
到了这里,关于go 笔记 十二章 断言 assertion 和 反射 reflect的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!