自学内容网 自学内容网

Golang 为什么需要用反射

本质上是可以动态获取程序运行时的变量(类型)

比如现在我想实现一个通用的db插入函数,支持我传入所有类型的struct,每一种类型的struct是一个单独的表,以struct的名称作为表名,然后插入到不同的表中。

package main

import (
"database/sql"
"fmt"
"reflect"

_ "github.com/go-sql-driver/mysql" // MySQL driver
)

// User 示例用户结构体
type User struct {
ID    int    `db:"id"`
Name  string `db:"name"`
Email string `db:"email"`
}

func main() {
db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/dbname")
if err != nil {
panic(err)
}
defer db.Close()

// 用户提供的任意结构体实例
user := User{
Name:  "Alice",
Email: "alice@example.com",
}

// 使用反射保存用户实例
save(db, user)
}

// save 通用保存函数,接受任何结构体实例作为参数
func save(db *sql.DB, model interface{}) error {
// 获取结构体实例的反射值和类型
val := reflect.ValueOf(model).Elem()
typ := val.Type()

// 构建INSERT SQL语句
var columns []string
var values []interface{}
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
columns = append(columns, field.Tag.Get("db"))
values = append(values, val.Field(i).Interface())
}

query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
typ.Name(), // 使用结构体名作为表名
strings.Join(columns, ", "),
strings.Repeat("?, ", len(columns)-1)+"?") // 参数占位符

// 执行SQL语句
result, err := db.Exec(query, values...)
if err != nil {
return err
}

// 返回受影响行数或其他信息
affected, err := result.RowsAffected()
if err != nil {
return err
}
fmt.Printf("Saved %d rows.\n", affected)

return nil
}


原文地址:https://blog.csdn.net/panguangyuu/article/details/137521864

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!