Commit bc405df3 authored by Robert Griesemer's avatar Robert Griesemer

spec: allow embedding overlapping interfaces

Updates #6977.

Change-Id: I6eda4be550e7c7ea1e1bac3222850002d90a81a8
Reviewed-on: https://go-review.googlesource.com/c/go/+/190378Reviewed-by: default avatarRob Pike <r@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 29d3c569
<!--{ <!--{
"Title": "The Go Programming Language Specification", "Title": "The Go Programming Language Specification",
"Subtitle": "Version of July 31, 2019", "Subtitle": "Version of Aug 26, 2019",
"Path": "/ref/spec" "Path": "/ref/spec"
}--> }-->
...@@ -1244,16 +1244,15 @@ The value of an uninitialized variable of interface type is <code>nil</code>. ...@@ -1244,16 +1244,15 @@ The value of an uninitialized variable of interface type is <code>nil</code>.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
InterfaceType = "interface" "{" { MethodSpec ";" } "}" . InterfaceType = "interface" "{" { ( MethodSpec | InterfaceTypeName ) ";" } "}" .
MethodSpec = MethodName Signature | InterfaceTypeName . MethodSpec = MethodName Signature .
MethodName = identifier . MethodName = identifier .
InterfaceTypeName = TypeName . InterfaceTypeName = TypeName .
</pre> </pre>
<p> <p>
As with all method sets, in an interface type, each method must have a An interface type may specify methods <i>explicitly</i> through method specifications,
<a href="#Uniqueness_of_identifiers">unique</a> or it may <i>embed</i> methods of other interfaces through interface type names.
non-<a href="#Blank_identifier">blank</a> name.
</p> </p>
<pre> <pre>
...@@ -1265,6 +1264,11 @@ interface { ...@@ -1265,6 +1264,11 @@ interface {
} }
</pre> </pre>
<p>
The name of each explicitly specified method must be <a href="#Uniqueness_of_identifiers">unique</a>
and not <a href="#Blank_identifier">blank</a>.
</p>
<pre> <pre>
interface { interface {
String() string String() string
...@@ -1280,9 +1284,9 @@ have the method set ...@@ -1280,9 +1284,9 @@ have the method set
</p> </p>
<pre> <pre>
func (p T) Read(p []byte) (n int, err error) { return … } func (p T) Read(p []byte) (n int, err error)
func (p T) Write(p []byte) (n int, err error) { return … } func (p T) Write(p []byte) (n int, err error)
func (p T) Close() error { return … } func (p T) Close() error
</pre> </pre>
<p> <p>
...@@ -1332,27 +1336,41 @@ as the <code>File</code> interface. ...@@ -1332,27 +1336,41 @@ as the <code>File</code> interface.
<p> <p>
An interface <code>T</code> may use a (possibly qualified) interface type An interface <code>T</code> may use a (possibly qualified) interface type
name <code>E</code> in place of a method specification. This is called name <code>E</code> in place of a method specification. This is called
<i>embedding</i> interface <code>E</code> in <code>T</code>; it adds <i>embedding</i> interface <code>E</code> in <code>T</code>.
all (exported and non-exported) methods of <code>E</code> to the interface The <a href="#Method_sets">method set</a> of <code>T</code> is the <i>union</i>
<code>T</code>. of the method sets of <code>T</code>’s explicitly declared methods and of
<code>T</code>’s embedded interfaces.
</p> </p>
<pre> <pre>
type ReadWriter interface { type Reader interface {
Read(b Buffer) bool Read(p []byte) (n int, err error)
Write(b Buffer) bool Close() error
} }
type File interface { type Writer interface {
ReadWriter // same as adding the methods of ReadWriter Write(p []byte) (n int, err error)
Locker // same as adding the methods of Locker Close() error
Close()
} }
type LockedFile interface { // ReadWriter's methods are Read, Write, and Close.
Locker type ReadWriter interface {
File // illegal: Lock, Unlock not unique Reader // includes methods of Reader in ReadWriter's method set
Lock() // illegal: Lock not unique Writer // includes methods of Writer in ReadWriter's method set
}
</pre>
<p>
A <i>union</i> of method sets contains the (exported and non-exported)
methods of each method set exactly once, and methods with the
<a href="#Uniqueness_of_identifiers">same</a> names must
have <a href="#Type_identity">identical</a> signatures.
</p>
<pre>
type ReadCloser interface {
Reader // includes methods of Reader in ReadCloser's method set
Close() // illegal: signatures of Reader.Close and Close are different
} }
</pre> </pre>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment