drhe80011 2016-07-15 10:03
浏览 217
已采纳

接口类型的Golang String方法

I am solving the problems for the book The Go Programming Language, and in exercise 7.13 it is required to add a String method to an interface.

Is this possible to add a String() method to an interface? Because the data type is not known until runtime.

  • 写回答

1条回答 默认 最新

  • duanmanpi9358 2016-07-15 10:07
    关注

    Adding a method to an interface just means to include that method in the method set defined by the interface type.

    For example this is an interface:

    type Fooer interface {
        Foo()
    }
    

    It has one method: Foo(). To add the String() method to this interface:

    type Fooer interface {
        Foo()
        String() string
    }
    

    Done. We have added the String() method to this interface.

    This has the consequence that if a concrete type wants to implement this Fooer interface, previously it was enough to have just a Foo() method. Now it also has to have a String() method.

    Also note that in Go implementing interfaces is implicit. There is no declaration of intent. A type implicitly satisfies an interface if it has all the methods of the interface.

    A concrete type may or may not have a String() method, independently from our Fooer interface. The concrete type may not even know about our Fooer interface, and it doesn't need to.

    Here's a concrete type implementating this Fooer interface:

    type fooerImpl int
    
    func (f fooerImpl) Foo() {
        fmt.Printf("Foo() called, I'm %d
    ", int(f))
    }
    
    func (f fooerImpl) String() string {
        return fmt.Sprintf("Foo[%d]", int(f))
    }
    

    Testing it:

    var f Fooer = fooerImpl(3)
    f.Foo()
    fmt.Println(f.String())
    fmt.Println(f)
    

    Output (try it on the Go Playground):

    Foo() called, I'm 3
    Foo[3]
    Foo[3]
    

    Consequences of adding a method to an interface

    If you arbitrarily add a new method to an interface, it may cause certain existing concrete types which previously implemented the interface to not implement it anymore (due to lack of the newly added method).

    If these existing concrete types were used as instances of the interface, they will cause a compile-time error and will not work until you add the missing new method. For example if we remove the fooerImpl.String() method from the above example, the code var f Fooer = fooerImpl(3) results in compile-time error:

    cannot use fooerImpl(3) (type fooerImpl) as type Fooer in assignment:
        fooerImpl does not implement Fooer (missing String method)
    

    If the existing concrete types were not used as instances of the interface directly, but e.g. they were passed around wrapped in the empty interface interface{} and type assertion was used to extract a value of the interface, those type assertions will not hold anymore. The "simple" form of type assertion x.(T) will result in a runtime panic, the special form v, ok := x.(T) will return nil and false.

    For example using the above fooerImpl type without the String() method:

    var f0 interface{} = fooerImpl(3)
    f := f0.(Fooer)
    

    Results in runtime panic:

    panic: interface conversion: main.fooerImpl is not main.Fooer: missing method String
    

    And using the special form of type conversion:

    if f, ok := f0.(Fooer); ok {
        f.Foo()
    } else {
        fmt.Println("Not instance of Fooer!", f)
    }
    

    Results in:

    Not instance of Fooer! <nil>
    

    If by any chance the existing concrete type already had a method which you have just added to the interface and it has the same signature (same parameter and return types), then that's cool, the concrete type will "continue" to implement the new interface too. If the signatures do not match (e.g. the existing method has different return type), then it will not satisfy the interface and it's the same as not having a method with the same name.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果