实现思路
- 参数处理:函数接收一个指向变量的指针,这样才能在函数内部修改外部变量的值。
- 反射获取信息:使用Go的反射包
reflect
获取传入值的类型和可设置性,并进行边界检查。
- 边界控制:不同类型有不同的边界,例如
Age
类型可能不能为负数,Weight
类型可能有最大最小值等,在设置值之前需要根据类型进行判断。
- 值的设置:使用反射的
Set
方法对变量进行赋值。
代码示例
package main
import (
"fmt"
"reflect"
)
// SetValueWithBoundary 通用函数,设置值并进行边界控制
func SetValueWithBoundary(target interface{}, value interface{}) error {
targetValue := reflect.ValueOf(target)
if targetValue.Kind() != reflect.Ptr {
return fmt.Errorf("target must be a pointer")
}
targetElem := targetValue.Elem()
if!targetElem.CanSet() {
return fmt.Errorf("target is not settable")
}
valueType := reflect.TypeOf(value)
if targetElem.Type() != valueType {
return fmt.Errorf("value type does not match target type")
}
switch valueType.Kind() {
case reflect.Int:
v := value.(int)
if targetElem.Type().String() == "Age" && v < 0 {
return fmt.Errorf("Age cannot be negative")
}
targetElem.SetInt(int64(v))
case reflect.Float32:
v := value.(float32)
if targetElem.Type().String() == "Weight" && (v < 0 || v > 1000) {
return fmt.Errorf("Weight should be between 0 and 1000")
}
targetElem.SetFloat(float64(v))
default:
return fmt.Errorf("unsupported type")
}
return nil
}
// Age 自定义类型
type Age int
// Weight 自定义类型
type Weight float32
测试代码
package main
import (
"fmt"
"testing"
)
func TestSetValueWithBoundary(t *testing.T) {
var a Age
err := SetValueWithBoundary(&a, 30)
if err != nil {
t.Errorf("Failed to set Age: %v", err)
}
if a != 30 {
t.Errorf("Expected Age to be 30, got %d", a)
}
var w Weight
err = SetValueWithBoundary(&w, 50.5)
if err != nil {
t.Errorf("Failed to set Weight: %v", err)
}
if w != 50.5 {
t.Errorf("Expected Weight to be 50.5, got %f", w)
}
err = SetValueWithBoundary(&a, -1)
if err == nil {
t.Errorf("Expected an error for negative Age, but got nil")
}
err = SetValueWithBoundary(&w, 1001)
if err == nil {
t.Errorf("Expected an error for Weight out of range, but got nil")
}
}