function to return an Interface

前端 未结 4 619
名媛妹妹
名媛妹妹 2021-02-07 08:27

The code below is really self-explanatory.

How come I can say that the result of CreateLion(), a pointer to a struct that implements the Cat interface, is an instance of

相关标签:
4条回答
  • 2021-02-07 08:58

    Works fine with a few changes. Check it out here: https://play.golang.org/p/ECSpoOIuzEx

    package main
    
    import "fmt"
    
    func main() {
        lion := CreateLion() // Go idomatic style recommends 
                             // allowing the compiler to divine the type
        lion.Meow()
    
        CatFactory := CreateLion
        _ = CatFactory // Go doesn't like unused variables and fails the build
    
        obj := CatFactory()     // exercising our factory method
        obj.Meow()
    }
    
    type Cat interface {
        Meow()
    }
    
    type Lion struct {}
    func (l Lion) Meow() {
        fmt.Println("Roar")
    }
    
    // define a functor that returns a Cat interface
    type CatFactory func() Cat
    
    // define a function that returns a pointer to a Lion struct
    func CreateLion() *Lion {
        return &Lion{}
    }
    

    Also, though Go doesn't have Java style interfaces, it does have interfaces and you can achieve polymorphism, but the types are known at compile time.

    You can model an "Is A" relationship, if both types implement the same interface. However it doesn't enforce the interface until you pass the object into a function that accepts that interface type. So if you imagine implementing the Strategy pattern, when you're passing in the strategy object matching interface "Cat", that function will accept a "Lion" object, or any other class that implements a Meow function with the correct signature.

    Also, factory methods are definitely necessary and useful in Go. In fact, instead of constructors, in Go, you use factory functions to construct your objects.

    0 讨论(0)
  • 2021-02-07 09:05

    The problem here is that statically typed go differentiates the "this is a function that returns a cat" from "this is a function that returns a lion that is a cat" And therefore will not accept one as the other.

    The way to fix this is to give your factory var exactly what it expects:

    var cf CatFactory = func() Cat{
        return CreateLion()
    }
    catlion := cf()
    catlion.Meow()
    
    0 讨论(0)
  • 2021-02-07 09:14

    I think you should read this blog http://blog.golang.org/laws-of-reflection,it is precise about the relation between variables,types and interfaces.

    In your example *Lion is different with Cat.

    You can correct function CreateLion returns from *Lion to Cat.

    0 讨论(0)
  • 2021-02-07 09:17

    Try this:

    package main
    
    import "fmt"
    
    type Cat interface {
        Meow()
    }
    
    type Lion struct{}
    
    func (l Lion) Meow() {
        fmt.Println("Roar")
    }
    
    type CatFactory func() Cat
    
    func CreateLion() Cat {
        return Lion{}
    }
    
    func main() {
        lion := CreateLion()
        lion.Meow()
    
        var cf CatFactory = CreateLion
        fLion := cf()
        fLion.Meow()
    }
    

    In most cases, you can assign any type to base type interface{}. But situation changes if type of function parameter is a map[T]interface{}, []interface{} or func() interface{}. In this case the type must be the same.

    0 讨论(0)
提交回复
热议问题