feat(go): 添加反射和函数调用功能
- 新增 Find 函数用于在切片中查找匹配项 - 定义 NamedItem 和 CurrencyItem 接口及其实现 - 添加 Purchase 类型的方法 calcTax 和 calcTotal - 实现 inspectFuncType、invokeFunction 和 mapSlice 反射工具函数 - 在 main28 中演示反射功能的使用 - 更新 main.go以调用 main28 函数
This commit is contained in:
13
27-reflection/reflection/functions.go
Normal file
13
27-reflection/reflection/functions.go
Normal 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
|
||||
}
|
||||
32
27-reflection/reflection/interfaces.go
Normal file
32
27-reflection/reflection/interfaces.go
Normal 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
|
||||
}
|
||||
@@ -25,4 +25,6 @@ func main() {
|
||||
main25()
|
||||
main26()
|
||||
main27()
|
||||
|
||||
main28()
|
||||
}
|
||||
|
||||
9
27-reflection/reflection/methods.go
Normal file
9
27-reflection/reflection/methods.go
Normal 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)
|
||||
}
|
||||
77
27-reflection/reflection/re3.go
Normal file
77
27-reflection/reflection/re3.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user