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

南楼画角 提交于 2019-12-20 08:23:58

问题


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)

回答1:


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)



回答2:


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.




回答3:


template.Must is the standard library's approach for returning only the first return value in one statement. Could be done similarly for your case:

func must(v interface{}, err error) interface{} {
    if err != nil {
        panic(err)
    }
    return v
}

// Usage:
str2 := must(twoRet()).(string)

By using must you basically say that there should never be an error, and if there is, then the program can't (or at least shouldn't) keep operating, and will panic instead.




回答4:


Or just in a single if:

if v, ok := value.(migrater); ok {
    v.migrate()
}

Go will take care of the cast inside the if clause and let you access the properties of the casted type.



来源:https://stackoverflow.com/questions/11403050/idiomatic-way-to-do-conversion-type-assertion-on-multiple-return-values-in-go

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!