【问题标题】:In Golang, can I assign slice values as return values?在 Golang 中,我可以将切片值分配为返回值吗?
【发布时间】:2014-08-08 17:09:07
【问题描述】:

我正在尝试开发一个传递函数,用于检查某些参数的评估,其余的则返回。但我希望这些作为多个返回值而不是一个切片返回。有没有办法在 Go 中做到这一点?这是一个例子:

func Check(args ...interface{}) ...interface{} {
    last := len(args) - 1
    err := args[last]

    // Check for an error in the last argument
    if err != nil {
        panic(err)
    }

    // Return any args returned by the function we're checking
    return ...args[:last]
}

我知道这在函数声明中的格式并不完全正确。这只是为了争论。理想情况下,我希望能够返回可变数量的值,然后可以通过赋值在另一端接收。当我想使用标准的 err/panic 习惯用法时,这将允许进行简单的内联错误检查。

我知道我可以返回切片,然后将其部分分配给各个变量,或者我可以创建多个这样的函数(例如 Check0、Check1、Check2 等),每个函数都有一个不同的数字或返回值,但是这些解决方案都不是很优雅。关于如何优雅地制作这样的东西的任何想法?或者在 Go 的这个阶段是不可能的?

在相关的说明中,有谁知道是否有计划将切片解压缩为变量,如下所示?

one, two, three := []string{"one", "two", "three"}

【问题讨论】:

  • 首先,坚持使用if err != nil { return err } 足够长的时间,让它不再烦人。你会习惯的,我发誓。如果您有一系列的 I/O 操作,并且整个程序或 HTTP 请求或任何东西必须崩溃并在它们中的任何一个因任何原因失败时显示错误,那么我认为panic()ing 包装器是可以的(不是当然大多数 Gophers 都同意),但即便如此,也不要使用 interface{};一种设计可能是一个名为must 的包,它导出ReadWrite 等函数,如n := must.Read(reader, p)must 的名称是从regexp.MustCompile 借来的。
  • 我认为切片永远不会在 Go 中解包,原因如下:如果切片不是预期的长度,解包会在运行时失败(就像我在Python),这使得它在精神上与现在存在的静态检查多个分配有很大不同。怀疑围棋人是否会将任务从安全的操作更改为可能引起恐慌的操作。
  • 是的,也许我应该坚持使用标准的错误形式。不知道。关于第二个问题,即使长度不同,它似乎也可以工作。如果变量少于切片成员,则丢弃剩余的值。如果变量多于切片成员,则将额外变量设置为 nil。然后可以根据需要对每个变量进行错误检查。似乎这种处理方式仍然普遍存在于 Go 精神中。将是一个非常方便的构造。
  • 此时我们只是为了好玩而谈论假设,但请注意,行为缺乏您现在获得的静态类型和计数检查,以及捕获我的一些 Python 错误的运行时异常. Perl 确实按照您的建议做,但是(回到具体问题)没有迹象表明 Go 会。

标签: go return-value variable-assignment slice idioms


【解决方案1】:

你不能这样做,我认为这甚至没有计划,这是 IMO 的一件好事。

你的选择是做这样的事情(这是丑陋的,不应该使用):

func Check(args ...interface{}) []interface{} {
    if err := args[len(args)-1]; err != nil {
        //do suff with err
    }
    args = args[:len(args)-1]
    return args
}

func Check2i(args ...interface{}) (int, int) {
    return args[0].(int), args[1].(int)
}

func main() {
    fmt.Println(Check(10, 20, 30, nil)...)
    a, b := Check2i(Check(10, 20, nil)...)
    _, _ = a, b
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-25
    • 2020-07-28
    • 2011-12-10
    • 2016-07-07
    • 2020-08-10
    • 2022-01-08
    • 2012-01-02
    相关资源
    最近更新 更多