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?
}
假设我有这个:
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?
}