como analisar vários retornos em golang

Eu tenho uma function go que retorna dois valores inteiros. abaixo é a function

func temp() (int, int){ return 1,1 } 

é possível colocar a function temp diretamente em um Println e imprimir ambas as saídas usando formatação de string como abaixo

 fmt.Println("first= %d and second = %d", temp() ) // This doesn't work 

Em Python, eu posso fazer o seguinte

 def func(): return 1,1 print("{0}={1}".format(*func()) >> '1=2' 

posso fazer algo semelhante em golang também?

Primeiro, você deve tentar usar fmt.Printf() vez de fmt.Println() pois somente o primeiro espera e usa uma string de formatação.

Indo adiante, isso não é suportado por padrão, porque citando Spec: Calls:

Como um caso especial, se os valores de retorno de uma function ou método g são iguais em número e individualmente atribuíveis aos parâmetros de outra function ou método f , então a chamada f(g(parameters_of_g)) chamará f após ligar os valores de retorno de g para os parâmetros de f em ordem. A chamada de f deve conter outros parâmetros além da chamada de g , e g deve ter pelo menos um valor de retorno. Se f tem um parâmetro final ... , é atribuído os valores de retorno de g que permanecem após a atribuição de parâmetros regulares.

E fmt.Printf() tem uma assinatura de:

 func Printf(format string, a ...interface{}) (n int, err error) 

Você não pode passar outros parâmetros para fmt.Printf() além de uma chamada de function (os valores de retorno da chamada).

Observe que a assinatura de fmt.Println() é:

 func Println(a ...interface{}) (n int, err error) 

O que significa que fmt.Println(temp()) funciona, assim como qualquer outra function que tenha pelo menos um valor de retorno, porque a última sentença da parte citada permite isto ( “Se f tem um parâmetro final ... , é atribuído os valores de retorno de g que permanecem após a atribuição de parâmetros regulares. “ )

Mas com um pequeno truque podemos conseguir o que você quer com fmt.Printf() também.

Note que se temp() retornaria um valor do tipo []interface{} , poderíamos usar ... para passá-lo como o valor de algum parâmetro variadico.

Significado isso funciona:

 func main() { fmt.Printf("1: %v, 2: %v\n", temp()...) } func temp() []interface{} { return []interface{}{1, 2} } 

E imprime corretamente (experimente no Go Playground ):

 1: 1, 2: 2 

Então, só precisamos de uma function de utilidade que envolva os valores de retorno de qualquer function em uma []interface{} , e assim podemos usar isso para passar para fmt.Printf() .

E é absolutamente simples:

 func wrap(vs ...interface{}) []interface{} { return vs } 

Como detalhado acima (com fmt.Println() ), podemos passar os valores de retorno de qualquer function que tenha pelo menos 1 valor de retorno para wrap() como os valores de seus parâmetros de input.

Agora usando esta function wrap() , veja o seguinte exemplo:

 func main() { fmt.Printf("1: %v\n", wrap(oneInt())...) fmt.Printf("1: %v, 2: %v\n", wrap(twoInts())...) fmt.Printf("1: %v, 2: %v, 3: %v\n", wrap(threeStrings())...) } func oneInt() int { return 1 } func twoInts() (int, int) { return 1, 2 } func threeStrings() (string, string, string) { return "1", "2", "3" } 

Isso funciona e produz (experimente no Go Playground ):

 1: 1 1: 1, 2: 2 1: 1, 2: 2, 3: 3 

Para mais informações sobre o assunto, veja a questão relacionada:

Vários valores no contexto de valor único

Mapa de retorno como ‘ok’ em Golang em funções normais

Não, isso não é possível. Você deve atribuir todos os valores de uma expressão com vários valores para separar variables ​​para usá-los, por exemplo:

 a, b := temp() fmt.Println("first = %d and second = %d", a, b) // first = 1 and second = 1 

[Editar]

Curiosamente, parece que, em alguns casos, você pode usar expressões de vários valores como argumentos de chamada de function se os tipos de argumento e aridade corresponderem, ou para funções puramente variadicas ( Ir para Playground ):

 func oneTwo() (int, int) { return 1, 2 } func incr2(x, y int) (int, int) { return x + 1, y + 1 } func main() { incr2(oneTwo()) // OK: multi-value return and arguments match. fmt.Println(oneTwo()) // OK: pure variadic function. fmt.Printf("%d %d", oneTwo()) // ERR: mixed formal and variadic args. } 

Consegui imprimi-lo quando não usei nenhuma formatação de string como abaixo

 fmt.Println(temp()) 

Isso foi suportado apenas pelo Println , mas não pelo printf

    Intereting Posts