在Go语言中,是否可以有选择地获取单值上下文中的返回值?

huangapple go评论75阅读模式
英文:

Is it possible to get return values selectively on single-value contexts in Go?

问题

一个简单的例子:

package main

import "fmt"

func hereTakeTwo() (x, y int) {
    x = 0
    y = 1
    return
}

func gimmeOnePlease(x int){
    fmt.Println(x)
}

func main() {
    gimmeOnePlease(hereTakeTwo()) // fix me
}

有没有可能在不使用显式的 _ 赋值的情况下,仅传递 hereTakeTwo() 的第一个返回值?我想要避免的示例:

func main() {
    okJustOne, _ := hereTakeTwo()
    gimmeOnePlease(okJustOne)
}

我想要的是使 gimmeOnePlease 函数能够接收一个未定义数量的参数,但只取第一个参数 或者 一种调用 hereTakeTwo 函数并仅获取第一个返回值的方法,而不需要使用 _ 赋值。

或者在最后的情况下(疯狂的想法),使用某种适配器函数,接受 N 个参数并仅返回第一个参数,然后像这样使用:

func main() {
    gimmeOnePlease(adapter(hereTakeTwo()))
}

为什么?我只是在测试语言的边界,并学习它在某些情况下的灵活性。

英文:

A simple example:

package main

import "fmt"

func hereTakeTwo() (x, y int) {
    x = 0
    y = 1
    return
}

func gimmeOnePlease(x int){
    fmt.Println(x)
}

func main() {
    gimmeOnePlease(hereTakeTwo()) // fix me
}

Is it possible to pass only first returned value from hereTakeTwo() without using an explicit _ assignment? Example of what I would like to avoid:

func main() {
    okJustOne, _ := hereTakeTwo()
    gimmeOnePlease(okJustOne)
}

What I want is to make gimmeOnePlease function able to receive an undefined number of arguments but take only first one OR a way to call hereTakeTwo function and get only first returned value without the necessity to use _ assignments.

Or on a last resort (crazy idea) use some kind of adapter function, that takes N args and reurns only first one, and have something like:

func main() {
    gimmeOnePlease(adapter(hereTakeTwo()))
}

Why? I'm just testing the boundaries of the language and learning how flexible it can be to some purposes.

答案1

得分: 8

不,除了规范中描述的一个特殊情况外,你不能这样做:

作为一个特殊情况,如果函数或方法g的返回值的数量与另一个函数或方法f的参数数量相等,并且每个返回值都可以分配给f的参数,那么调用f(g(g的参数))将在按顺序将g的返回值绑定到f的参数后调用f。调用f除了调用g之外不能包含其他参数,而且g必须至少有一个返回值。

除了使用临时变量(这是最好的选择)之外,你可以尝试以下方法:

func first(a interface{}, _ ...interface{}) interface{} {
    return a
}

func main() {
    gimmeOnePlease(first(hereTakeTwo()).(int))
}

Playground: http://play.golang.org/p/VXv-tsYjXt

可变参数版本:http://play.golang.org/p/ulpdp3Hppj

英文:

No, you cannot do that apart from one special case described in the Spec:

>As a special case, if the return values of a function or method g are equal in number and individually assignable to the parameters of another function or method f, then the call f(g(parameters_of_g)) will invoke f after binding the return values of g to the parameters of f in order. The call of f must contain no parameters other than the call of g, and g must have at least one return value.

The best you can do besides the temporary variables (which are the best option) is this:

func first(a interface{}, _ ...interface{}) interface{} {
    return a
}

func main() {
	gimmeOnePlease(first(hereTakeTwo()).(int))
}

Playground: http://play.golang.org/p/VXv-tsYjXt

Variadic version: http://play.golang.org/p/ulpdp3Hppj

huangapple
  • 本文由 发表于 2014年12月1日 21:22:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/27229402.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定