loading...

A simple way to ensure interface won’t be implemented accidently

#go
dannypsnl profile image 林子篆 Originally published at dannypsnl.github.io on ・1 min read

Sample code is quite easy:

type Car interface {
    impl() Car
    Move()
}

type Animal interface {
    impl() Animal
    Walk()
}

Now, let’s create a structure type:

type Duck struct {
    Animal
}

Now, if you add func (d *Duck) Move(), you won’t be a car accident! What if you want to embed two interfaces?

type Duck struct {
    Car
    Animal
}

The compiler would refuse the code since: Duck.impl is ambiguous, you can’t have two methods with the same name in Go definition. So we can use this to create something just like impl Trait for Type in Rust, although this is a workaround,but anyway I work with Go so I have to find out how to ensure this when we need it.

If you want to know what if we want something just take type has Move() method? Then just define:

type Movable interface {
    Move()
}

The point is correctly reduce the concept in interface, and do not create interface has general name, unless you know what are you doing,but if you need a workaround, this is.

Since Go can’t write: func foo(bar A + B + C), A, B, C are interface, so I suggest write:

func foo(bar interface{
    A
    B
    C
})

NOTE: newline is required, because Go compiler is stupid. You might want define a private interface for this function only.

Sad thing is we can’t use A | B | C, have to do runtime assertion for this.

One more bad thing is because you embedded the interface, Go won’t check you provide the implementation of methods or not, you have to do this manually.

Posted on by:

dannypsnl profile

林子篆

@dannypsnl

I am a programming language theory lover; good at system software like Networking, OS.

Discussion

markdown guide
 

Note you can do:

func foo(bar interface{ A; B; C; })

Even if it is not the gofmt style...

 

Few reasons why I don't show that:

  • as you say, gofmt would reformat it, in the most environment, gofmt is trigger by default
  • Go using newline to separate things in interface, at least, from user view it's, so semicolon would confuse others. Which means you just expose the details, I would that's a parser bug, since it should not allow the thing it does not courage you do.
 

It is not a parser bug, it is the go grammar. Perhaps do you think the grammar should be augmented? If yes, you can submit a proposal.
Just as a note one can read the go specification and more specifically the semicolons point.

Do you read the whole sentence? I say it's a bug since... I explain why I don't prefer that code, not try to get a specification reference, I read that a lot ok.
And then change the syntax almost impossible, it might break some code so Go won't accept it.
I have to point out: Go is ok, but of course not prefer, like any other thing.
If you can't accept anyone says it's a problem, fine, just end the conversation.