Idiomatic way to do conversion/type assertion on multiple return values in Go
Solution 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)
Solution 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.
Solution 3:
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.
Solution 4:
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.