通过引用将不同类型的变量作为参数传递到同一可变参数

Passing variables of different types by reference as arguments to same variadic parameter

提问人:Gabe Tucker 提问时间:6/25/2022 最后编辑:Gabe Tucker 更新时间:6/25/2022 访问量:272

问:

我一直在为 golang 缺乏可选参数而苦苦挣扎,所以我一直在使用最接近的解决方法:可变调。即使我让它工作,尝试通过引用将多个变量类型传递给同一个可变参数也很麻烦:

// back-end
func UpdateRef(variadic ...*interface{}) {
    for _, v := range variadic {
        if v.(type) == string {
            *v = "New ref val"
        }
    }
}

// front-end
func Interface(x interface{}) interface{} { return &x }
func main() {
    ref := Interface("Hey") // starts as "Hey"
    i := Interface(500)
    UpdateRef(&ref, &i) // ends at "New ref val"
}

如果我用这个替换前端:

// front-end
func main() {
    ref := "Hey" // starts as "Hey"
    UpdateRef(ref, 500) // ends at "New ref val"
}

...那么我怎样才能改变后端,使所需的前端代码工作呢?后端可以根据需要尽可能详细,只要所需的前端按原样运行即可。这可能吗?如果没有,有没有一个优雅的解决方案,需要对所需的前端进行最少的更改?

函数 go 参数 参数传递 by-reference

评论

0赞 colm.anseo 6/25/2022
首先,几乎没有实际理由使用指向接口的指针 - 尤其是空的 .interface{}
0赞 colm.anseo 6/25/2022
其次,如果您想要函数的可选输入,传递带有可选字段值的结构可能是更好的路由。
0赞 Gabe Tucker 6/25/2022
@colm.anseo 1)原因是我需要通过引用传递任意变量类型。我是否缺少一种没有接口指针的方法?2)如果我执行结构路由,那么我仍然会遇到必须在前端执行其他步骤以将参数传递给UpdateRef的问题,这是我试图避免的。
4赞 colm.anseo 6/25/2022
您可以传递指针(如果要更新指向值,则需要传递指针),但参数类型可以简单地interface{}
0赞 Gabe Tucker 6/25/2022
@colm.anseo 根据您所说的内容,我使用上面代码片段中所需的前端部分设置了一个测试。然后,我将 的参数设置为类型 。然后我运行了与原始后端相同的 for 循环,除了没有设置 ,而是设置了 .执行此操作后从我的函数打印,它仍然返回“Hey”,而不是“New ref val”。我做错了吗?UpdateRefvariadic...interface{}*vv = "New ref val"refmain

答:

2赞 wuqinqiang 6/25/2022 #1

你只是

package main

import (
    "reflect"
)

// back-end
func UpdateRef(variadic ...interface{}) {
    for _, v := range variadic {
        kind := reflect.TypeOf(v).Kind()
        if kind == reflect.Pointer {
            reflect.ValueOf(v).Elem().Set(reflect.ValueOf("New ref val"))
        }
    }
}

// front-end
func main() {
    ref := "Hey"         // starts as "Hey"
    // To modify a reflection object, the value must be settable.
    UpdateRef(&ref, 500) // ends at "New ref val"
    println(ref)
}

查看 Golang 博客:https://go.dev/blog/laws-of-reflection

编码快乐!

评论

1赞 Gabe Tucker 6/25/2022
非常感谢您的回答!我将 RedBlue 的答案标记为正确,只是因为他提供了一个不依赖于反思的解决方案,但您的建议非常有效,我感谢您的帮助。
3赞 2 revsuser12258482 #2

用作参数类型。对指针类型的类型断言。 取消引用指针以设置值。interface{}

func UpdateRef(variadic ...interface{}) {
    for _, v := range variadic {
        if v, ok := v.(*string); ok {
            *v = "New ref val"
        }
    }
}

传递指向函数的指针:

ref := "Hey"
i := 500
UpdateRef(&ref, &i)
fmt.Println(ref)  // prints “New ref val”