Golang:你能在一个语句中输入一个返回的接口{}吗?

Golang: Can you type a returned interface{} in one statement?

假设我有这个:

type Donut string
type Muffin string

func getPastry () (interface{}, error) {
  // some logic - this is contrived
  var d Donut
  d = "Bavarian"
  return d, nil
}

是否可以将其缩减为一行:

p, err := getPastry()
thisPastry := p.(Donut)

换句话说,像这样的东西,不能编译:

thisPastry, err := getPastry().(Donut, error)

并不是说用两行代码来获取 "generic" 并输入它是一件大事,但对我来说这只是一种浪费和不简单的感觉,这通常意味着我遗漏了一些明显的东西:-)

你不能。你能做的最好的事情就是编写一个辅助函数(并在其中进行类型断言):

func getDonut(p interface{}, err error) (Donut, error) {
    return p.(Donut), err
}

然后变成一行:

d, err := getDonut(getPastry())

或者您甚至可以 "incorporate" getPastry() 在辅助函数中调用:

func getDonutPastry() (Donut, error) {
    p, err := getPastry()
    return p.(Donut), err
}

然后调用它(更短的一行):

d, err := getDonutPastry()

注:

当然,如果 getPastry() 编辑的值 return 不是动态类型 Donut,这将是 运行 时间恐慌。为防止这种情况,您可以使用 type assertion:

的特殊形式
v, ok := x.(T)

这会产生一个额外的无类型布尔值。如果断言成立,ok 的值为 true。否则它是 false 并且 v 的值是类型 T 的零值。在这种情况下不会发生 运行 次恐慌。

使用特殊形式的辅助函数的安全版本可能如下所示(它们 return 一个错误而不是恐慌):

func getDonut2(p interface{}, err error) (Donut, error) {
    if d, ok := p.(Donut); ok {
        return d, err
    } else {
        return "", errors.New("Not a Donut!")
    }
}

func getDonutPastry2() (Donut, error) {
    p, err := getPastry()
    if d, ok := p.(Donut); ok {
        return d, err
    } else {
        return "", errors.New("Not a Donut!")
    }
}

查看相关问题:

简答:不可能。

长答案:
它将更容易被更多人阅读和理解,因为没有长行将很多东西链接在一起。

在您的示例中,我假设您将必须测试错误,然后检查松饼等。 为了非常清楚您期望哪些类型以及如何处理它们,您可以进行类型切换:

thisPastry, err := getPastry()
if err != nil { ... }

switch v := thisPastry.(type) {
case Donut:
    fmt.Println(v)
case Muffin:
    fmt.Println(v, "mmm!")
default:
    // some kind of error?
}