【问题标题】:Is it necessary to use a type assertion to access the values of a type returned by interface?是否有必要使用类型断言来访问接口返回的类型的值?
【发布时间】:2014-11-25 16:26:56
【问题描述】:

当我有一个返回接口类型的函数时,返回的值不会像我期望的那样工作。也就是说,它严格充当已定义的接口,要访问接口中未定义的方法和值,我必须进行类型断言。为什么?

考虑以下示例代码:

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?或者类型断言真的是最好的方法吗?

【问题讨论】:

    标签: go type-conversion go-interface


    【解决方案1】:

    不知道在这里回答什么。也许对什么是接口类型存在误解。接口类型是绝对正常的类型。你可以用接口值来做接口所说的:调用接口方法。对于结构类型,您可以访问字段并调用结构类型定义的接口方法。所以一切都很简单:一个类型允许它允许的东西,无论是接口还是结构。

    现在碰巧一个接口类型的值可能包含一些结构值(比如说)。到目前为止,这是隐藏的。类型断言揭示了结构值(并且没有更多的接口)。您可以在接口中隐藏其他结构值(假设它实现了正确的方法),这可能没有Value 字段。这清楚地表明,如果没有类型断言,您将无法访问 Value 字段,因为它可能不存在。

    【讨论】:

      【解决方案2】:

      如果你需要访问接口实现的内部值(Value),你必须要么通过接口本身暴露它,要么做一个类型断言。那是因为Frobnicator 中没有任何内容表明它是 Foo 还是其他一些实现结构。

      它与许多其他语言没有什么不同。在 Java 中,您也必须在类似情况下进行强制转换。

      【讨论】:

      • 那么interface{} 是一个特例吗?或者当一个值作为interface{} 类型传递直到某些东西被转换为另一种类型时,nothing 是否可以访问?
      • interface{} 不是特例,它只是一个退化的常规情况。在投射之前,interface{} 将无法提供任何内容。
      猜你喜欢
      • 2021-12-05
      • 2020-08-06
      • 2019-09-02
      • 1970-01-01
      • 1970-01-01
      • 2015-07-15
      • 2023-04-03
      • 1970-01-01
      • 2016-10-03
      相关资源
      最近更新 更多