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

rai*_*308 4 interface go type-assertion multiple-return-values

假设我有这个:

type Donut string
type Muffin string

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

是否可以将其减少到一行:

p, err := getPastry()
thisPastry := p.(Donut)
Run Code Online (Sandbox Code Playgroud)

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

thisPastry, err := getPastry().(Donut, error)
Run Code Online (Sandbox Code Playgroud)

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

icz*_*cza 7

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

func getDonut(p interface{}, err error) (Donut, error) {
    return p.(Donut), err
}
Run Code Online (Sandbox Code Playgroud)

然后它变成了一条线:

d, err := getDonut(getPastry())
Run Code Online (Sandbox Code Playgroud)

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

func getDonutPastry() (Donut, error) {
    p, err := getPastry()
    return p.(Donut), err
}
Run Code Online (Sandbox Code Playgroud)

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

d, err := getDonutPastry()
Run Code Online (Sandbox Code Playgroud)

注意:

当然,如果返回的值getPastry()不是动态类型Donut,那么这将是运行时混乱.为了防止这种情况,您可以使用类型断言的特殊形式:

v, ok := x.(T)
Run Code Online (Sandbox Code Playgroud)

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

使用特殊形式的辅助函数的安全版本可能看起来像这样(它们返回错误而不是恐慌):

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!")
    }
}
Run Code Online (Sandbox Code Playgroud)

查看相关问题:

在普通函数中返回Golang中的'ok'映射

Go:单值上下文中的多个值

  • IMO这个例子显示了不好的做法,因为我们在没有检查错误的情况下进行类型断言,其中包装函数给人的印象是它会返回错误而不是恐慌. (2认同)