我如何将字典作为函数的参数列表,如Python 3中的Go?
Python 3:def bar(a,b,c):
print(a,b,c)
args={c: 1, b: 2, a: 3}
bar(**args)
空白:
func bar( a, b, c int) {
fmt.Printf("%d, %d, %d", a, b, c)
}
func main(){
args := make(map[string]int)
args["a"] = 3
args["b"] = 2
args["c"] = 1
// what next ?
}
我不相信这是可能的。你需要使用一个结构体来做任何类似的事情
type Args struct {
A, B, C int
}
func bar(args *Args) {
fmt.Printf("%d, %d, %d", args.A, args.B, args.C)
}
func main() {
args := new(Args)
args.A = 3
args.B = 2
args.C = 1
bar(args)
}
除了我认为没有必要重复的其他答案之外,请注意Go将自动解包提供多个返回参数的函数调用:
- 每个返回值都是函数 的一个参数
- 每个参数都是函数 的返回值
(也就是说,函数的实参列表的类型与另一个函数的返回列表的类型相同)。
func Args() (a int, b int, c int) {
return 1,2,3
}
func Bar(a,b,c int) {
fmt.Println(a,b,c)
}
func main() {
Bar(Args())
}
将打印1,2,3
。显然这个例子有点傻,但我发现它涵盖了Python中元组和字典作为参数解包的大多数情况,这往往是一种快速而肮脏的方式,将一个函数的返回值作为另一个函数的参数传递。
为了完整起见,你可以使用dskinner所说的,或者如果你想要一个"字典"(在Go中称为map),你可以很容易地使用一个,对于example
:
package main
import "log"
type ArgsMap map[string]interface{}
func bar(am ArgsMap) {
if v, ok := am["foo"].(string); ok {
log.Println("bar", v)
} else {
log.Println("bar no foo")
}
}
// Or
type Args struct {
foo string
boo int
a, b, c float32
}
func bar2(a Args) {
if a.foo != "" {
log.Println("bar2", a.foo)
} else {
log.Println("bar2 no foo")
}
}
func main() {
bar(ArgsMap{"foo": "map", "blah": 10})
bar(ArgsMap{})
bar2(Args{foo: "struct"})
bar2(Args{})
}
没有直接等价于Python的*args/**kwargs
语法。您需要使用其他答案中列出的解决方案之一。
如果你只需要传递一个未知数量的参数,你可以让你的函数变进。
package main
import (
"fmt"
)
func bar(numbers ...int) {
fmt.Printf("%dn", numbers)
}
func main() {
bar(3, 2, 1) // prints [3 2 1]
bar(5, 4, 3, 2, 1) // prints [5 4 3 2 1]
}
玩这并没有针对广泛的值进行彻底的测试,但它适用于一些简单的情况。您可以根据自己的需要对其进行进一步扩展。它也不能保证是最好的方法,错误检查留给读者作为练习。
func parseArguments(args ...interface{}) map[string]interface{} {
if args == nil {
return nil
}
if x,ok := args[0].(map[string]interface{}); ok {
return x
}
x := map[string]interface{}{}
for i := 0; i < len(args); i += 2 {
x[ args[i].(string) ] = args[i+1]
}
return x
}
func DoSomethingCool(x ...interface{}) {
args := parseArguments(x);
// args is now a map of type map[string]interface{}
}
你现在可以用以下任何一种方式调用DoSomethingCool()
:
// No arguments
DoSomethingCool()
// These two are equivalent, and result in
// args = map[string]interface{}{
// "foo": "bar",
// "baz": "qux",
// }
DoSomethingCool(map[string]string{"foo": "bar", "baz": "qux"})
DoSomethingCool("foo","bar","baz","qux")
// Or you can even mix types for the keys, thanks to interface{}
// These two are also equivalents and result in
// args = map[string]interface{}{
// "foo": 20,
// "bar": false,
// }
DoSomethingCool(map[string]interface{}{"foo": 20, "bar": false})
DoSomethingCool("foo",20,"bar",false)
如果您不需要混合值类型,我想您也可以使用map[string]string
。