Ensure a type implements an interface at compile time in Go

后端 未结 6 1400
悲&欢浪女
悲&欢浪女 2020-11-30 08:51

How can I ensure that a type implements an interface at compile time? The typical way to do this is by failure to assign to support interfaces from that type, however I have

6条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-30 09:24

    Extending the answer by @smile-on.

    In How can I guarantee my type satisfies an interface?, which is part of the Frequently Asked Questions (FAQ) by the Go Authors, the following is stated:

    You can ask the compiler to check that the type T implements the interface I by attempting an assignment using the zero value for T or pointer to T, as appropriate.

    We can illustrate this with an example:

    package main
    
    type I interface{ M() }
    type T struct{}
    
    func (T) M() {}
    
    //func (*T) M() {} //var _ I = T{}: T does not implement I (M method has pointer receiver)
    
    func main() {
      //avoids allocation of memory
      var _ I = T{}       // Verify that T implements I.
      var _ I = (*T)(nil) // Verify that *T implements I.
      //allocation of memory
      var _ I = &T{}      // Verify that &T implements I.
      var _ I = new(T)    // Verify that new(T) implements I.
    }
    

    If T (or *T, accordingly) doesn't implement I, the mistake will be caught at compile time. See Non-interface methods in interface implementation.

    Typically you check if a value implements an interface if you don't know its type. If it is known, the check is done by the compiler automatically. See Explanation of checking if value implements interface.

    The blank identifier _ stands for the variable name, which is not needed here (and thus prevents a "declared but not used" error). (*T)(nil) creates an uninitialized pointer to a value of type T by converting nil to *T. See Have trouble understanding a piece of golang code.

    This is the same value which, for example, var t *T has before assigning anything to it. See golang interface compliance compile type check. This avoids allocation of memory for an empty struct as you'd get with &T{} or new(T). See Have trouble understanding a piece of golang code.

    Quotes edited to match example.

提交回复
热议问题