go 反射 interface{} 判断类型 获取值 设置值 指针才可以设置值

news/2025/2/23 1:12:15

内容包括

1. 用interface{}接收值

2. 判断interface{}的类型 switch

3. 打印interface{}的类型

4. 通过字符串对结构体,interface{}等进行设置值、获取值处理

示例代码

package main

import (
    "fmt"
    "log"
    "reflect"
)

type Student2 struct {
    Id1   int `json:"jsonTag1" db:"name2"`
    Name1 string
    age1  int
}

func reflectValue(a interface{}) {
    log.Println("================ reflect value start ==================")
    // 类型判断
    switch a.(type) {
    case float64:
       log.Println("a type is :", "float64")
    case float32:
       log.Println("a type is :", "float32")
    default:
       log.Println("a type is :", "default")
    }

    // 打印类型
    aType := reflect.TypeOf(a)
    log.Println("a type is:", aType)

    // 获取值
    aValue := reflect.ValueOf(a)
    log.Println("a value is :", aValue.Float())

    // 设置值报错,不传指针就没办法设置值
    // 报错信息:panic: reflect: reflect.Value.SetFloat using unaddressable value
    // aValue.SetFloat(32.11)
    // log.Println("a value is :", aValue.Float())

    log.Println("================ reflect value end ==================")
}

func reflectPoint(a interface{}) {
    log.Println("================ reflect point start ==================")

    // 打印类型
    aType := reflect.TypeOf(a)
    log.Println("a type is:", aType)

    // 判断类型
    aKind := aType.Kind()
    switch aKind {
    case reflect.Float64:
       log.Println("a kind is :", "float64")
    case reflect.Float32:
       log.Println("a kind is :", "float32")
    case reflect.Pointer:
       log.Println("a kind is :", "Pointer")
    }

    // 获取参数
    aValue := reflect.ValueOf(a)
    log.Println("a value is :", aValue.Elem().Float())

    // 设置参数
    aValue.Elem().SetFloat(32.1)
    log.Println("a value is :", aValue.Elem().Float())

    log.Println("================ reflect point end ==================")
}

func reflectStructValue(a interface{}) {
    log.Println("================ reflect struct value start ==================")

    // 获取类型
    aType := reflect.TypeOf(a)
    log.Println("a type of :", aType)
    log.Println("a type name :", aType.Name())

    // 获取值{100 name1 13}
    aValue := reflect.ValueOf(a)
    log.Println("a value of :", aValue)

    // 根据名称获取字段
    // 如果外边传的是value则没法赋值,如果传的是$stu地址 则可以复制
    name1Filed := aValue.FieldByName("Name1")
    if name1Filed.Kind() == reflect.String && name1Filed.CanSet() {
       name1Filed.SetString("name1111111111")
    }

    // 遍历属性
    fieldNum := aType.NumField()
    for i := 0; i < fieldNum; i++ {
       field := aType.Field(i)
       value := aValue.Field(i)
       // 这里得看属性是否大小写,如果小写没法子获取他的值
       // panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
       // 获取字段标记:field.Tag.Get("json")
       if value.CanInterface() {
          log.Println("属性:", field.Name, field.Type, value.Interface(), field.Tag.Get("json"))
       } else {
          log.Println("属性:", field.Name, field.Type)
       }
    }

    // 遍历方法
    // func (stu Student2) Say()  可以获取到
    // func (stu *Student2) Say() aType.NumMethod就没法获取到了
    methodNum := aType.NumMethod()
    for i := 0; i < methodNum; i++ {
       method := aType.Method(i)
       log.Println("方法:", method.Name, method.Type)
    }

    // 根据名称获取方法,并执行
    sayMethod := aValue.MethodByName("Say")
    args := []reflect.Value{reflect.ValueOf("message1111")}
    sayMethod.Call(args)

    log.Println("================ reflect struct value end ==================")

}

func reflectStructPoint(a interface{}) {
    log.Println("================ reflect struct point start ==================")

    // 获取值{100 name1 13}
    aValue := reflect.ValueOf(a)
    log.Println("a value of :", aValue.Elem().Interface())

    // 根据名称获取字段
    // 如果外边传的是value则没法赋值,如果传的是$stu地址 则可以复制
    name1Filed := aValue.Elem().FieldByName("Name1")
    if name1Filed.Kind() == reflect.String && name1Filed.CanSet() {
       name1Filed.SetString("name1111111111")
    }
    log.Println("a value of :", a)
    log.Println("a value of :", aValue.Elem().Interface())

    log.Println("================ reflect struct point start ==================")
}

func (stu Student2) Say(message string) {
    log.Println("student say:", stu, message)
}

func main() {
    log.Println("main ...")
    var f float64 = 10
    // 传地址可以修改
    reflectPoint(&f)
    // 传值就不能修改
    reflectValue(f)

    stu := Student2{100, "name1", 13}
    stu.Say("1111")
    reflectStructValue(stu)
    reflectStructPoint(&stu)

    fmt.Println("success ...")
}

参考:

https://www.topgoer.com/%E5%B8%B8%E7%94%A8%E6%A0%87%E5%87%86%E5%BA%93/%E5%8F%8D%E5%B0%84.html


http://www.niftyadmin.cn/n/5862896.html

相关文章

MYSQL-数据库-DDL-DML-DQL-DCL-基础学习

MySql概念&#xff1a; 建立在关系模型基础上&#xff0c;有多张相互连接的二维表组成的数据库 SQL通用语法&#xff1a; 1.SQL语句可以单行或多行书写&#xff0c;以分号结尾 2.SQL语句可以使用空格/缩进来增强语句的可读性 3.MySQL数据库的SQL语句不区分大小写&#xff0c;关…

基于FPGA的制冷型红外成像电路设计(论文+图纸)

1.总体设计 对于本次课题基于FPGA的制冷型红外成像电路设计&#xff0c;其主要包括两个功能&#xff0c;第一就是红外图像的显示&#xff0c;第二就是红外图像中各点温度的测量。首先对于红外图像的显示来说&#xff0c;一般根据红外探测器根据阵列的大小可以显示出不同的清晰度…

深入理解 Rust 的 `Rc<T>`:实现多所有权的智能指针

一、为什么需要多所有权&#xff1f; 通常&#xff0c;我们习惯于每个值只有一个所有者&#xff0c;这样编译器在值离开作用域时就能自动释放资源。然而&#xff0c;在某些数据结构中&#xff0c;一个节点可能会被多个其他结构同时引用——比如图结构中的节点或共享链表的一部…

Powershell Install deepseek

前言 deepseekAI助手。它具有聊天机器人功能&#xff0c;可以与用户进行自然语言交互&#xff0c;回答问题、提供建议和帮助解决问题。DeepSeek 的特点包括&#xff1a; 强大的语言理解能力&#xff1a;能够理解和生成自然语言&#xff0c;与用户进行流畅的对话。多领域知识&…

MySQL日常维护工具------备份

MySQL日常维护工具-备份 一、MySQL字符集 &#xff08;一&#xff09;字符集介绍 字符(Character)是各种文字和符号的总称&#xff0c;包括各国家文字、标点符号、图形符号、数字等。字符集(Character set)是多个字符的集合&#xff0c;字符集种类较多&#xff0c;每个字符集…

力扣练习题笔记

788. 旋转数字 788. 旋转数字 - 力扣&#xff08;LeetCode&#xff09; 代码 class Solution { public:int rotatedDigits(int n) {//数中没有3&#xff0c;4&#xff0c;7//数中至少出现一次2或5&#xff0c;6或9//对于0&#xff0c;1&#xff0c;8无要求int ans 0;for(int…

HarmonyOS NEXT 开发实战指南(基于API 12+)

一、HarmonyOS NEXT 核心特性解析 1.1 分布式能力升级 跨设备服务协同&#xff1a;通过ServiceExtensionAbility实现服务原子化拆分&#xff0c;支持设备间按需调用 // 服务提供方声明 "abilities": [{"name": "CameraService","type&qu…

vscode复制到下一行

linux中默认快捷键是ctrl shift alt down/up 但是在vscode中无法使用&#xff0c;应该是被其他的东西绑定了&#xff0c;经测试&#xff0c;可以使用windows下的快捷键shift alt down/up { “key”: “shiftaltdown”, “command”: “editor.action.copyLinesDownAction”…