如何在不指定类型的情况下修改函数输入参数?

阿甘:

我试图使一个函数接受2个参数,并将第二个参数的值设置为第一个参数,它可能看起来像(我不确定):

func set(a interface{}, b interface{}) {
  // do something to make a = b
}

它是这样的:

a := 0
b := 10
set(&a, b)
// here a should be 10

s1 := ""
s2 := "what"
set(&s1, s2)
// here s1 should be "what"

它应该适用于所有基本类型,例如int,float,string,bool等。

我该如何实现?

icza:

使用反射可以做到这一点:

func set(a interface{}, b interface{}) {
    reflect.ValueOf(a).Elem().Set(reflect.ValueOf(b))
}

请注意,此代码不会检查是否a为指针,并且其元素类型是否与中的值的类型匹配b另请注意,使用反射速度较慢,并且会失去编译时类型的安全性。上面的代码比将单个intint分配给变量或将string分配给变量要慢得多string

测试它:

a := 0
b := 10
set(&a, b)
fmt.Println(a)

s1 := ""
s2 := "what"
set(&s1, s2)
fmt.Println(s1)

输出(在Go Playground上尝试):

10
what

这是一个添加检查以避免运行时出现紧急情况的版本:

func set(a interface{}, b interface{}) error {
    v1 := reflect.ValueOf(a)
    if v1.Kind() != reflect.Ptr {
        return errors.New("a must be pointer")
    }
    if v1.IsZero() {
        return errors.New("a must not be a nil pointer")
    }

    v1 = v1.Elem()
    v2 := reflect.ValueOf(b)
    if v1.Type() != v2.Type() {
        return errors.New("a's element type must match b's type")
    }

    if !v1.CanSet() {
        return errors.New("unsettable value in a")
    }

    v1.Set(v2)
    return nil
}

测试它:

a := 0
b := 10
err := set(a, b)
fmt.Printf("set(a, b): a=%v, err: %v\n", a, err)
err = set(&a, b)
fmt.Printf("set(&a, b): a=%v, err: %v\n", a, err)
err = set((*int)(nil), b)
fmt.Printf("set((*int)(nil), b): a=%v, err: %v\n", a, err)

s1 := ""
s2 := "what"
err = set(&s1, s2)
fmt.Printf("set(&s1, s2): s1=%v, err: %v\n", s1, err)
err = set(&s1, b)
fmt.Printf("set(&s1, s2): s1=%v, err: %v\n", s1, err)

输出(在Go Playground上尝试):

set(a, b): a=0, err: a must be pointer
set(&a, b): a=10, err: <nil>
set((*int)(nil), b): a=10, err: a must not be a nil pointer
set(&s1, s2): s1=what, err: <nil>
set(&s1, s2): s1=what, err: a's element type must match b's type

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在函数的参数中不使用类型的情况下指定函数的类型?

如何在不指定类的情况下使用显式类型参数调用Java方法?

如何在不循环的情况下从函数参数中指定的json数组中获取密钥?

如何在不指定构造函数的情况下从列表中提取可区分的联合类型?

如何在不使用assert的情况下指定函数输入和输出的类型?

在不传递指针的情况下修改函数的参数

PostgreSQL:如何在不指定参数的情况下删除存在的功能?

如何在不指定Java Enum类型的情况下引用我的Java Enum

如何在不指定模板类型的情况下声明通用抽象类的对象

如何在不指定组件类型的情况下将父组件注入共享指令?

如何在不指定共享类型的情况下使用Box Java SDK创建共享链接?

如何在不指定模板的情况下声明函数模板指针typedef?

如何在不声明 SQL Server 类型的情况下使用参数插入多个值?

如何在不声明不同变量的情况下将这些输入放入函数中

如何在不对聚合组的keyf函数进行任何更改的情况下指定原始参数

如何在不为可选参数指定值的情况下迅速调用以下函数?

spring如何在不传递参数的情况下实例化@Autowired构造函数

编译器如何在不更改参数列表的情况下重载模板函数?

如何在不展开包装的情况下将ref传递给方法/函数参数?

如何在不访问Java母函数的情况下将参数传递给回调

如何在不更改Metric类型的情况下使函数返回双精度?

如何在不指定final的情况下访问变量?

如何在不限制其尺寸的情况下为函数参数指定类型?

如何在不阻塞输入的情况下使用getline?

如何在不循环 login() 的情况下输入 main()

如何在不知道形式参数类型的情况下找到构造函数?

PyCharm:如何在提示输入参数的情况下运行?

如何在不丢失其类型的情况下将rxjava2 Zip函数(从Single / Observable)的可归纳性推广到n个Nullable参数?

如何在不丢失其类型的情况下将rxjava2 Zip函数(从Single / Observable)的可归纳性推广到n个Nullable参数?