Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic way to do conversion/type assertion on multiple return values in Go

What is the idiomatic way to cast multiple return values in Go?

Can you do it in a single line, or do you need to use temporary variables such as I've done in my example below?

package main  import "fmt"  func oneRet() interface{} {     return "Hello" }  func twoRet() (interface{}, error) {     return "Hejsan", nil }  func main() {     // With one return value, you can simply do this     str1 := oneRet().(string)     fmt.Println("String 1: " + str1)      // It is not as easy with two return values     //str2, err := twoRet().(string) // Not possible     // Do I really have to use a temp variable instead?     temp, err := twoRet()     str2 := temp.(string)     fmt.Println("String 2: " + str2 )       if err != nil {         panic("unreachable")     }    } 

By the way, is it called casting when it comes to interfaces?

i := interface.(int) 
like image 459
ANisus Avatar asked Jul 09 '12 20:07

ANisus


2 Answers

You can't do it in a single line. Your temporary variable approach is the way to go.

By the way, is it called casting when it comes to interfaces?

It is actually called a type assertion. A type cast conversion is different:

var a int var b int64  a = 5 b = int64(a) 
like image 109
jimt Avatar answered Sep 28 '22 09:09

jimt


func silly() (interface{}, error) {     return "silly", nil }  v, err := silly() if err != nil {     // handle error }  s, ok := v.(string) if !ok {     // the assertion failed. } 

but more likely what you actually want is to use a type switch, like-a-this:

switch t := v.(type) { case string:     // t is a string case int :     // t is an int default:     // t is some other type that we didn't name. } 

Go is really more about correctness than it is about terseness.

like image 43
jorelli Avatar answered Sep 28 '22 08:09

jorelli