gpt4 book ai didi

go - 在方法声明中允许可变数量的返回值

转载 作者:IT王子 更新时间:2023-10-29 01:09:40 26 4
gpt4 key购买 nike

我有一个函数可以解决 Go 不允许在方法声明中设置默认值的问题。我想通过允许可变数量的返回变量来让它变得更好一点。我知道我可以允许接口(interface)数组作为返回类型,然后创建一个接口(interface)数组,其中包含要返回的所有变量,如下所示:

func SetParams(params []interface{}, args ...interface{}) (...[]interface{}) {
var values []interface{}
for i := range params {
var value interface{}
paramType := reflect.TypeOf(params[i])
if len(args) < (i + 1) {
value = params[i]
} else {
argType := reflect.TypeOf(args[i])
if paramType != argType {
value = params[i]
}
value = args[i]
}
values = append(values, value)
}

return values
}

这是您要为其定义默认值的方法示例。您将其构建为可变参数函数(允许可变数量的参数),然后在函数内部而不是在声明行中定义您要查找的特定参数的默认值。

func DoSomething(args ...interface{}) {
//setup default values
str := "default string 1"
num := 1
str2 := "default string 2"


//this is fine
values := SetParams([]interface{str, num, str2}, args)
str = values[0].(string)
num = values[1].(int)
str = values[2].(string)


//I'd rather support this
str, num, str2 = SetParams(params, args)
}

我明白了

[]interface{str, num, str2}

在上面的例子中语法不正确。我这样做是为了简化我的帖子。但是,它代表了另一个构建接口(interface)数组的函数。

我愿意支持这个:

str, num, str2 = SetParams(params, args)

不必这样做:

values := SetParams([]interface{str, num, str2}, args)
str = values[0].(string)
num = values[1].(int)
str = values[2].(string)

有什么建议吗?帮忙?

最佳答案

请不要编写可怕的(由于 reflect 而无效)的代码来解决不存在的问题。正如评论中指出的那样,将一种语言变成你以前的一种语言确实很有说服力切换后,但这会适得其反。

相反,最好使用习语和方法以及该语言提供的最佳实践——即使您不喜欢它们(现在,也许)。

对于这种特殊情况,您可以像这样滚动:

  • 制作想要接受的函数具有默认值的参数列表接受自定义 struct 类型的单个值。

  • 首先,分配此类类型的任何变量时,它的所有字段都用所谓的“零值”初始化适合各自的类型。

    如果够了,你可以到此为止:你将能够将您的 struct 类型的值传递给您的函数通过在调用站点通过文字生成它们——仅初始化您需要的字段。

    否则有预处理/后处理代码将为字段提供您自己的“零值”你需要。

2016-08-29 更新:

使用struct 类型来模拟可选参数使用其字段被分配默认值发生成为各自数据类型的 Go 原生零值:

package main

import (
"fmt"
)

type params struct {
foo string
bar int
baz float32
}

func myfun(params params) {
fmt.Printf("%#v\n", params)
}

func main() {
myfun(params{})
myfun(params{bar: 42})
myfun(params{foo: "xyzzy", baz: 0.3e-2})
}

输出:

main.params{foo:"", bar:0, baz:0}
main.params{foo:"", bar:42, baz:0}
main.params{foo:"xyzzy", bar:0, baz:0.003}

如你所见,Go 初始化了我们的 params 类型的字段具有适合其各自类型的零值除非我们在定义文字时指定我们自己的值。

Playground link.

提供不是 Go-native 零值的默认值我们自定义类型的字段可以通过或对用户提交的复合类型值进行后处理。

后处理:

package main

import (
"fmt"
)

type params struct {
foo string
bar int
baz float32
}

func (pp *params) setDefaults() {
if pp.foo == "" {
pp.foo = "ahem"
}
if pp.bar == 0 {
pp.bar = -3
}
if pp.baz == 0 { // Can't really do this to FP numbers; for demonstration purposes only
pp.baz = 0.5
}
}

func myfun(params params) {
params.setDefaults()
fmt.Printf("%#v\n", params)
}

func main() {
myfun(params{})
myfun(params{bar: 42})
myfun(params{foo: "xyzzy", baz: 0.3e-2})
}

输出:

main.params{foo:"ahem", bar:-3, baz:0.5}
main.params{foo:"ahem", bar:42, baz:0.5}
main.params{foo:"xyzzy", bar:-3, baz:0.003}

Playground link.

预处理相当于创建一个“构造函数”这将返回预填充的所需类型的值使用您为其字段选择的默认值——某物像这样:

func newParams() params {
return params{
foo: "ahem",
bar: -3,
baz: 0.5,
}
}

这样你函数的调用者就可以调用newParams(),如果需要,调整其字段,然后传递结果值到你的功能:

myfunc(newParams())

ps := newParams()
ps.foo = "xyzzy"
myfunc(ps)

这种方法可能比后处理更稳健,但它排除了使用文字来构造要传递给的值您的功能就在不太“整洁”的调用站点。

关于go - 在方法声明中允许可变数量的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39177189/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com