章节

16.6 反射调用结构体方法

本篇学习 MethodByName 和 Call 的使用方式,并能通过反射调用结构体方法。

反射调用结构体方法

概念说明

反射不仅能查看字段,也可以按方法名调用方法。
常见做法是用 MethodByName 找到方法,再用 Call 传入参数。

这种方式会牺牲编译期检查。
只有在框架、插件、动态分发等场景下才更适合使用。

语法/规则

  1. 使用 reflect.ValueOf(value).MethodByName("方法名") 查找方法。
  2. 方法不存在时返回无效值,可以用 IsValid() 判断。
  3. Call 的参数类型是 []reflect.Value
  4. Call 的返回值也是 []reflect.Value
  5. 只能通过反射直接找到可导出方法。

调用方法示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
	"fmt"
	"reflect"
)

type User struct {
	Name string
}

func (user User) Hello(prefix string) string {
	return prefix + " " + user.Name
}

func main() {
	user := User{Name: "abin"}
	method := reflect.ValueOf(user).MethodByName("Hello") // 按方法名查找方法
	if !method.IsValid() {
		panic("method not found")
	}

	results := method.Call([]reflect.Value{ // Call 的参数要写成 []reflect.Value
		reflect.ValueOf("hello"),
	})

	fmt.Println(results[0].String())
}

输出结果:

1
hello abin

常见错误

  1. 方法名写错后不检查 IsValid(),直接调用导致 panic。
  2. Call 参数数量或类型不匹配,运行时才报错。
  3. 试图调用未导出方法,反射无法按普通方式直接调用。
  4. 能用普通方法调用时仍使用反射,降低可读性和类型安全。
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字