Opaque interfaces and the golang spec

469 views
Skip to first unread message

spo...@gopivotal.com

unread,
Apr 28, 2014, 6:15:40 AM4/28/14
to golan...@googlegroups.com
Recently I saw this:

Unfortunately, the Opaque interface isn't a private implementation at all. Anyone could come along and implement it themselves. But what if we modify our original interface definition to be this instead:

type Opaque interface {                   // Public
        GetNumber() int                   // Public
        implementsOpaque()                // Private
}

Now we have a public interface, Opaque, but it contains a private method implementsOpaque. Within my package I am free to define implementsOpaque because it's visible, so I can make the internalBasicType conform to the Opaque interface with one line:

func (m *internalBasicType) implementsOpaque() {}


Now, whereas I don't agree with the conclusion of this blog, this notion of opaque interfaces intrigued me. I immediately thought of the ways another package might use the Opaque interface, and I considered embedding it.  Why not embed Opaque in another interface type and simply implement the methods for the new one?

I went to the language spec to see what it said about interface types and "lower-case" methods, and it is silent. In fact, what it says is wrong:

An interface may use an interface type name T in place of a method specification. The effect, called embedding an interface, is equivalent to enumerating the methods of T explicitly in the interface.

and this is exactly what does not happen.  Although you can embed Opaque  in another interface type definition, it is impossible to implement the new interface. I put Opaque in pkga and wrote this:

package pkgb
import "iftest/pkga"
type MyInterface interface {
pkga.Opaque
}
type OB int
func (OB) implementsOpaque() {}
func (OB) GetNumber() int    { return 0 }
func TestAFunc() {
var x MyInterface
var y OB
x = y
}

and the compiler gives messages like:

# iftest/pkgb
./pkgb.go:17: cannot use y (type OB) as type MyInterface in assignment:
OB does not implement MyInterface (missing pkga.implementsOpaque method)
have implementsOpaque()
want pkga.implementsOpaque()

whereas implementsOpaque ought to be a method in interface MyInterface, just like GetNumber is.

Whether the spec should change or the compiler is a moot point, but something's gotta give.

Ian Lance Taylor

unread,
Apr 28, 2014, 10:57:55 AM4/28/14
to spo...@gopivotal.com, golang-nuts
Good point. I think the spec should change. Would you mind opening
an issue at http://golang.org/issue/new ? Thanks.

Ian

zteve....@gmail.com

unread,
Apr 28, 2014, 11:49:03 AM4/28/14
to golan...@googlegroups.com, spo...@gopivotal.com
I've raised an issue number 7886. Unfortunately, due to strange corporate restrictions, I couldn't raise this under the same id as the original post; but it's me; honest.
Reply all
Reply to author
Forward
0 new messages