当我有一个返回接口类型的函数时,返回的值不能像我期望的那样工作。也就是说,它严格地作为定义的接口,并且为了访问接口中未定义的方法和值,我必须做一个类型断言。为什么呢?
请考虑以下示例代码:
package main
import (
"fmt"
)
type Frobnicator interface {
Frobnicate()
}
type Foo struct {
Value string
}
func (f *Foo) Frobnicate() {
fmt.Printf("The value is %s\n", f.Value)
}
func fooFactory () Frobnicator {
return &Foo{"chicken"}
}
func main() {
foo := fooFactory( )
foo.Frobnicate()
// foo.Value undefined (type Frobnicator has no field or method Value)
// fmt.Printf("foo value = %s\n", foo.Value)
bar := foo.(*Foo)
fmt.Printf("bar value = %s\n", bar.Value)
}
是否有更好,更轻松,更惯用的方式来foo.Value
?或者类型断言真的是最好的方法吗?
答案 0 :(得分:2)
如果需要访问接口实现(Value)的内部值,则必须通过接口本身公开它或执行类型断言。这是因为Frobnicator
中没有任何内容表明它是否是Foo或其他一些实现结构。
与许多其他语言没什么不同。在Java中,你也必须在类似情况下进行投射。
答案 1 :(得分:2)
不确定在这里回答什么。也许有一种误解是什么接口类型。接口类型绝对是普通类型。您可以使用接口所指的接口值:调用接口方法。对于结构类型,您可以访问字段并调用结构类型定义的接口方法。所以一切都很简单:类型允许它允许的内容,无论是接口还是结构。
现在碰巧接口类型的值可能包含一些结构值(比方说)。到目前为止,这是隐藏的。类型断言显示结构值(并且没有更多接口)。您可以在界面中隐藏其他结构值(假设它实现了正确的方法),这可能没有Value
字段。这清楚地表明,如果没有类型断言,您将无法访问Value
字段,因为它可能不存在。