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 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog