42.1 F
Columbus
Tuesday, January 26, 2021

Diamond interface composition in Go 1.14

This post was originally published on this site

Per the overlapping interfaces proposal, Go 1.14 now permits embedding of interfaces with overlapping method sets. This is a brief post explain what this change means:

Let’s start with the definition of the three key interfaces from the io package; io.Reader, io.Writer, and io.Closer:

package io

type Reader interface {
    Read([]byte) (int, error)
}

type Writer interface {
    Write([]byte) (int, error)
}

type Closer interface {
    Close() error
}    

Just as embedding a type inside a struct allows the embedded type’s fields and methods to be accessed as if it were declared on the embedding type1, the process is true for interfaces. Thus there is no difference between explicitly declaring

type ReadCloser interface {
    Read([]byte) (int, error)
    Close() error
}

and using embedding to compose the interface

type ReadCloser interface {
    Reader
    Closer
}

You can even mix and match

type WriteCloser interface {
    Write([]byte) (int, error)
    Closer
}

However, prior to Go 1.14, if you continued to compose interface declarations in this manner you would likely find that something like this,

type ReadWriteCloser interface {
    ReadCloser
    WriterCloser
}

would fail to compile

% go build interfaces.go
command-line-arguments
./interfaces.go:27:2: duplicate method Close

Fortunately, with Go 1.14 this is no longer a limitation, thus solving problems that typically occur with diamond-shaped embedding graphs.

However, there is a catch that I ran into attempting to demonstrate this feature to the local user group–this feature is only enabled when the Go compiler uses the 1.14 (or later) spec.

As near as I can make out the rules for which version of the Go spec is used during compilation appear to be:

  1. If your source code is stored inside GOPATH (or you have disabled modules with GO111MODULE=off) then the version of the Go spec used to compile with matches the version of the compiler you are using. Said another way, if you have Go 1.13 installed, your Go version is 1.13. If you have Go 1.14 installed, your version is 1.14. No surprises here.
  2. If your source code is stored outside GOPATH (or you have forced modules on with GO111MODULE=on) then the go tool will take the Go version from the go.mod file.
  3. If there is no Go version listed in go.mod then the version of the spec will be the version of Go installed. This is identical to point 1.
  4. If you are in module mode, either by being outside GOPATH or with GO111MODULE=on, but there is no go.mod file in the current, or any parent, directory then the version of the Go spec used to compile your code defaults to Go 1.13.

The last point caught me out.

Related Articles

Announcing the launch of our Slack V.3 integration

In 2018, we released an integration between Stack Overflow for Teams and Slack. It’s now one of the most popular ways for users to...

IntelliJ IDEA 2020.3.2 Is Available

Our second bug-fix release for IntelliJ IDEA 2020.3.2 is out! You can upgrade to v2020.3.2 from the IDE, with the Toolbox App, or by...

Answering Your Questions: AMA with the .NET Team on Reddit

Last week, we held our first Ask Me Anything (AMA) session on Reddit. We’d like to thank everyone who participated, and we hope you...

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Stay Connected

21,422FansLike
0FollowersFollow
0SubscribersSubscribe
- Advertisement -

Latest Articles

Announcing the launch of our Slack V.3 integration

In 2018, we released an integration between Stack Overflow for Teams and Slack. It’s now one of the most popular ways for users to...

IntelliJ IDEA 2020.3.2 Is Available

Our second bug-fix release for IntelliJ IDEA 2020.3.2 is out! You can upgrade to v2020.3.2 from the IDE, with the Toolbox App, or by...

Answering Your Questions: AMA with the .NET Team on Reddit

Last week, we held our first Ask Me Anything (AMA) session on Reddit. We’d like to thank everyone who participated, and we hope you...

WebStorm 2020.3.2 Is Available

WebStorm 2020.3.2, the second bug-fix update for WebStorm 2020.3, is now available! You can update to it using the Toolbox App or right from the...

Video: Refactoring Code With PhpStorm

Christoph Rumpel shows PhpStorm’s refactoring features. He goes through 6 refactorings to improve code readability and maintainability. https://youtube.com/watch?v=LamxHRmwK2Q PhpStorm tips with Christoph Rumpel is a video...