I think the confusion comes from how you're exposing each interface -- or 
rather, how you seem to imply their use.

In your example, you provide packages pet and filepath each of which define 
a Walk interface *plus* one or more structs that implement that interface. 
But, neither package consumes the Walk interface they define.  This is what 
Jack 
Lindamood refers to as a *preemptive interface* and it's contrary to 
idiomatic Go.

While your usage pattern is quite common in Java (or similar) -- where a 
package exposes a public interface as a "contract" for its behavior and is 
then free to change its implementing class behind the scenes (as long as it 
continues to implement the published interface) -- that is not how Go 
interfaces are meant to be used.  Instead, a Go interface should be defined 
in the package where it will be received in an argument list and the 
"contract" is defined by the documentation for the interface (e.g. "If you 
hand me a Fooer, I'm going call Foo() under these conditions and expect it 
to do A, B and C.").  This way, anyone can implement that interface and 
pass it as an argument to your function (or method).

This is why most Go interfaces define very few methods (often only one).

If you stick to only defining an interface when and where you actually need 
one -- and live by the adage "Accept interfaces, return structs" -- I think 
this will make a lot more sense.

See the following for more info:

   - Preemptive Interface Anti-Pattern in Go 
   
<https://medium.com/@cep21/preemptive-interface-anti-pattern-in-go-54c18ac0668a>
   - What “accept interfaces, return structs” means in Go 
   
<https://medium.com/@cep21/what-accept-interfaces-return-structs-means-in-go-2fe879e25ee8>
   

t.


On Wednesday, August 8, 2018 at 10:21:55 PM UTC-7, Ally Dale wrote:
>
> Hi everyone,
> I have some confusion about GO's interface:
> 1. Some different interface but with the same signature
> I have put an example here: 
> https://github.com/vipally/glab/blob/master/lab12/walk_test.go
> The confusion is, there are two different interface filepath.Walker and 
> pet.Walker.
> filepath.Walker is designed for "visit all files of a filepath"
> pet.Walker is designed for "walk action of animals"
> But unfortunately, both signature is the same:
> type Walker interface {
>  Walk()
> }
>
> But in go syntax, the follow usage is legal:
> var petWalker pet.Walker
> petWalker = &filepath.FilePath{}
> petWalker.Walk()
>
> But it's obviously that this usage is out of plan.
> 2. Cannot find all types that has implements an interface
> Go tools is hard to find type pet.Dog and pet.Cat through pet.Walker,
> Because there is no declarations of the relations between them.
>
> Maybe this outter-declaration can solve this problem?
> //declare which types has implements this interface
> implements pet.Walker{
>  *pet.Dog
>  *pet.Cat
> }
> //declare this type has implement any interfaces
> implements *filepath.FilePath{
>   filepath.Walker
>   filepath.Reader
> }
>
>
>
>
> Ally.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to