Golang 为什么需要用反射

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

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

Go 复制代码
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
}
相关推荐
江畔柳前堤3 小时前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
Wang's Blog4 小时前
Go-Zero 项目开发47:自研微服务框架的必要性与核心结构设计
开发语言·微服务·golang
白鸽(二般)4 小时前
MinIO Java Client API
java·开发语言
hPw0eKIqD4 小时前
C++ 模板参数推导问题小记(非推导上下文)
开发语言·c++
临床数据科学和人工智能兴趣组5 小时前
要使用 R Markdown,首先需要安装 R 和 RStudio,接着安装 rmarkdown 包
开发语言·数据挖掘·数据分析·r语言·r语言-4.2.1
Nebula嵌入式5 小时前
【C语言】09-深入解析main函数
linux·c语言·开发语言·嵌入式
陈随易5 小时前
moon,apt和yum之外linux系统命令安装新选择
前端·后端·程序员
码事漫谈6 小时前
当单库日增 4.5TB,异构实时同步还能稳得住吗?
后端
神罚天下ET7 小时前
c# ACME client (补充)
开发语言·c#
小灰灰搞电子7 小时前
Qt 实现魔法导航菜单源码分享
开发语言·qt