将函数的返回值作为输入参数传递给另一个函数。

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

Return values of function as input arguments to another

问题

如果我有以下代码:

func returnIntAndString() (i int, s string) {...}

func doSomething(i int, s string) {...}

然后我可以成功执行以下操作:

doSomething(returnIntAndString())

然而,假设我想在doSomething中添加另一个参数,像这样:

func doSomething(msg string, i int, s string) {...}

当我像这样调用它时,Go 在编译时会报错:

doSomething("message", returnIntAndString())

错误信息为:

main.go:45: multiple-value returnIntAndString() in single-value context
main.go:45: not enough arguments in call to doSomething()

有没有办法解决这个问题,或者我应该放弃,将returnIntAndString的返回值赋值给一些引用,并像doSomething(msg, code, str)这样传递消息和这些值?

英文:

If I have

func returnIntAndString() (i int, s string) {...}

And I have:

func doSomething(i int, s string) {...}

Then I can do the following successfully:

doSomething(returnIntAndString())

However, let's say I want to add another argument to doSomething like:

func doSomething(msg string, i int, s string) {...}

Go complains when compiling if I call it like:

doSomething("message", returnIntAndString())

With:

main.go:45: multiple-value returnIntAndString() in single-value context
main.go:45: not enough arguments in call to doSomething()

Is there a way to do this or should I just give up and assign the return values from returnIntAndString to some references and pass msg and these values like doSomething(msg, code, str) ?

答案1

得分: 18

在规范中这里有详细描述。它要求内部函数对所有参数返回正确的类型。不允许在返回多个值的函数中使用额外的参数。

作为特例,如果函数或方法g的返回值数量与另一个函数或方法f的参数数量相等,并且每个返回值都可以分别赋值给f的参数,则调用f(g(g的参数))将按顺序将g的返回值绑定到f的参数上。调用f除了调用g之外不能包含其他参数,并且g必须至少有一个返回值。如果f有一个最终的...参数,则该参数将被赋予g的返回值,这些返回值在分配了常规参数之后仍然存在。

func Split(s string, pos int) (string, string) {
	return s[0:pos], s[pos:]
}

func Join(s, t string) string {
	return s + t
}

if Join(Split(value, len(value)/2)) != value {
	log.Panic("test fails")
}

如果不满足这些特定条件,则需要分别赋值返回值并调用函数。

英文:

It's described here in the spec. It requires the inner function to return the correct types for all arguments. There is no allowance for extra parameters along with a function that returns multiple values.

> 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. If f has a final ...
> parameter, it is assigned the return values of g that remain after
> assignment of regular parameters.
>
> func Split(s string, pos int) (string, string) {
> return s[0:pos], s[pos:]
> }
>
> func Join(s, t string) string {
> return s + t
> }
>
> if Join(Split(value, len(value)/2)) != value {
> log.Panic("test fails")
> }

If those specific conditions are not met, then you need to assign the return values and call the function separately.

答案2

得分: 0

我有同样的问题。我能想到的最好的解决方案是创建我所需的额外参数的类型或结构,并为它们编写方法,就像这样:

package main

import (
	"fmt"
)

type Message string

type MessageNumber struct {
	Message string
	Number  int
}

func testfunc() (foo int, bar int) {
	foo = 4
	bar = 2
	return
}

func (baz Message) testfunc2(foo int, bar int) {
	fmt.Println(foo, bar, baz)
}

func (baz MessageNumber) testfunc3(foo int, bar int) {
	fmt.Println(foo, bar, baz.Number, baz.Message)
}

func main() {
	Message("the answer").testfunc2(testfunc())
	MessageNumber{"what were we talking about again?", 0}.testfunc3(testfunc())
	fmt.Println("Done. Have a day.")
}

输出结果如下:

4 2 the answer
4 2 0 what were we talking about again?
Done. Have a day.
英文:

I had the same question. The best solution I could come up with is creating types or structs for my desired extra parameters and writing methods for them like this:

package main

import (
	"fmt"
)

type Message string

type MessageNumber struct {
	Message string
	Number int
}

func testfunc() (foo int, bar int) {
	foo = 4
	bar = 2
	return
}

func (baz Message) testfunc2(foo int, bar int) {
	fmt.Println(foo, bar, baz)
}

func (baz MessageNumber) testfunc3(foo int, bar int) {
	fmt.Println(foo, bar, baz.Number, baz.Message)
}

func main() {
	Message("the answer").testfunc2(testfunc())
	MessageNumber{"what were we talking about again?", 0}.testfunc3(testfunc())
	fmt.Println("Done.  Have a day.")
}

The output looks like this:

user@Frodos-Atari-MEGA-STE:~/go/test$ go run main.go
4 2 the answer
4 2 0 what were we talking about again?
Done.  Have a day.

huangapple
  • 本文由 发表于 2016年2月9日 00:31:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/35274528.html
匿名

发表评论

匿名网友

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

确定