feat(go): 添加反射和函数调用功能

- 新增 Find 函数用于在切片中查找匹配项
- 定义 NamedItem 和 CurrencyItem 接口及其实现
- 添加 Purchase 类型的方法 calcTax 和 calcTotal
- 实现 inspectFuncType、invokeFunction 和 mapSlice 反射工具函数
- 在 main28 中演示反射功能的使用
- 更新 main.go以调用 main28 函数
This commit is contained in:
2025-11-01 21:42:57 +08:00
parent 4092ddd6d8
commit 67f35e7e77
5 changed files with 133 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package main
func Find(slice []string, vals ...string) (matches bool) {
for _, item := range slice {
for _, val := range vals {
if item == val {
matches = true
return
}
}
}
return
}

View File

@@ -0,0 +1,32 @@
package main
import "fmt"
type NamedItem interface {
GetName() string
unexportedMethod()
}
type CurrencyItem interface {
GetAmount() string
currencyName() string
}
func (p *Product) GetName() string {
return p.Name
}
func (p *Product) GetAmount() string {
return fmt.Sprintf("$%.2f", p.Price)
}
func (p *Product) currencyName() string {
return "USD"
}
func (p *Product) unexportedMethod() {
}
func (c *Customer) GetName() string {
return c.Name
}

View File

@@ -25,4 +25,6 @@ func main() {
main25()
main26()
main27()
main28()
}

View File

@@ -0,0 +1,9 @@
package main
func (p Purchase) calcTax(taxRate float64) float64 {
return p.Price * taxRate
}
func (p Purchase) calcTotal() float64 {
return p.Price + p.calcTax(0.20)
}

View File

@@ -0,0 +1,77 @@
package main
import (
"reflect"
"strings"
)
func inspectFuncType(f interface{}) {
Printfln("\ninspectFuncType:")
funcType := reflect.TypeOf(f)
if funcType.Kind() != reflect.Func {
Printfln("Not a function")
return
}
Printfln("Function parameters count: %v", funcType.NumIn())
for i := 0; i < funcType.NumIn(); i++ {
paramType := funcType.In(i)
if i < funcType.NumIn()-1 {
Printfln("Parameter #%v, Type: %v", i, paramType)
} else {
Printfln("Parameter #%v, Type: %v, Variadic: %v", i, paramType, funcType.IsVariadic())
}
}
Printfln("Function results count: %v", funcType.NumOut())
for i := 0; i < funcType.NumOut(); i++ {
resultType := funcType.Out(i)
Printfln("Result #%v, Type: %v", i, resultType)
}
}
func invokeFunction(f interface{}, params ...interface{}) {
Printfln("\ninvokeFunction:")
paramVals := []reflect.Value{}
for _, p := range params {
paramVals = append(paramVals, reflect.ValueOf(p))
}
funcVal := reflect.ValueOf(f)
if funcVal.Kind() == reflect.Func {
results := funcVal.Call(paramVals)
for i, result := range results {
Printfln("Result #%v: %v", i, result)
}
}
}
func mapSlice(slice interface{}, mapper interface{}) (mapped []interface{}) {
Printfln("\nmapSlice:")
sliceVal := reflect.ValueOf(slice)
mapperVal := reflect.ValueOf(mapper)
mapped = []interface{}{}
if sliceVal.Kind() == reflect.Slice &&
mapperVal.Kind() == reflect.Func &&
mapperVal.Type().NumIn() == 1 &&
// 函数参数0的参数类型等于数组元素的参数类型
mapperVal.Type().In(0) == sliceVal.Type().Elem() {
for i := 0; i < sliceVal.Len(); i++ {
result := mapperVal.Call([]reflect.Value{sliceVal.Index(i)})
for _, r := range result {
mapped = append(mapped, r.Interface())
}
}
}
return
}
func main28() {
Printfln("\nmain28:")
inspectFuncType(Find)
names := []string{"Alice", "Bob", "Charlie"}
invokeFunction(Find, names, "London", "Bob")
results := mapSlice(names, strings.ToUpper)
Printfln("Results: %v", results)
}