Идиоматический способ выполнения преобразования/утверждения типа для нескольких возвращаемых значений в Go
Каков идиоматический способ применения нескольких возвращаемых значений в Go?
Можете ли вы сделать это в одной строке или вам нужно использовать временные переменные, например, я сделал в моем примере ниже?
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")
}
}
Кстати, называется ли это casting
, когда дело доходит до интерфейсов?
i := interface.(int)
Ответы
Ответ 1
Вы не можете сделать это в одной строке.
Ваш временный переменный подход - это путь.
Кстати, это называется литье, когда дело доходит до интерфейсов?
На самом деле это называется утверждение типа.
Преобразование типа cast отличается:
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.
}
но более вероятно, что вы действительно хотите использовать переключатель типа, например-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 действительно больше о правильности, чем о терпении.
Ответ 3
template.Most - это стандартный библиотечный подход для возврата только первого возвращаемого значения в один оператор. Это можно сделать аналогично для вашего случая:
func must(v interface{}, err error) interface{} {
if err != nil {
panic(err)
}
return v
}
// Usage:
str2 := must(twoRet()).(string)
Используя must
, вы в основном говорите, что никогда не должно быть ошибки, и если есть, то программа не может (или, по крайней мере, не должна) продолжать работать, и будет паниковать вместо этого.
Ответ 4
Или просто в одном, если:
if v, ok := value.(migrater); ok {
v.migrate()
}
Go позаботится о литье внутри предложения if и даст вам доступ к свойствам литого типа.