Skip to content

Commit 71cd69a

Browse files
committed
Add doc for interface satisfaction
1 parent d4be4cc commit 71cd69a

File tree

7 files changed

+116
-1
lines changed

7 files changed

+116
-1
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
// In go+, interfaces do not need to be explicitly implemented – i.e. no implement keyword. Instead, interfaces are satisfied implicitly.
3+
4+
// A type satisfies an interface if it possesses all the methods the interface requires. For example,
5+
// an *os.File satisfies io.Reader, io.Writer, io.Closer, and io.ReadWriter. A *bytes.Buffer satisfies io.Reader, io.Writer, and io.ReadWriter, but does not satisfy io.Closer because it does not have a
6+
// Close method.
7+
8+
// The assignability rule for interfaces is very simple: an expression may be assigned to
9+
// an interface only if its type satisfies the interface. This rule applies even when the right-hand side is itself an interface. For example:
10+
11+
import (
12+
"bytes"
13+
"io"
14+
"os"
15+
"time"
16+
)
17+
18+
var w io.Writer
19+
20+
w = os.Stdout // OK: *os.File has Write method
21+
w = new(bytes.Buffer) // OK: *bytes.Buffer has Write method
22+
w = time.Second // compile error: time.Duration lacks Write method
23+
24+
var rwc io.ReadWriteCloser
25+
rwc = os.Stdout // OK: *os.File has Read, Write, Close methods
26+
rwc = new(bytes.Buffer) // compile error: *bytes.Buffer lacks Close method
27+
28+
w = rwc // OK: io.ReadWriteCloser interface has Write method
29+
rwc = w // compile error: io.Writer interface lacks Close method
30+
31+
// Because io.ReadWriter and io.ReadWriteCloser include all the methods of io.Writer, any type that
32+
// satisfies io.ReadWriter or io.ReadWriteCloser necessarily satisfies io.Writer.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Like an envelope that wraps and conceals the letter it holds, an interface wraps and conceals
2+
// the concrete type and value that it holds. Only the methods revealed by the interface type may
3+
// be called, even if the concrete type has others. For example:
4+
5+
import (
6+
"io"
7+
"os"
8+
)
9+
10+
os.Stdout.Write([]byte("hello")) // OK: *os.File has Write method
11+
os.Stdout.Close() // OK: *os.File has Close method
12+
var w io.Writer
13+
w = os.Stdout
14+
w.Write([]byte("hello")) // OK: io.Writer has Write method
15+
w.Close() // compile error: io.Writer lacks Close method
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// A concrete type may satisfy many unrelated interfaces. Consider a program that organizes or
2+
// sells digitized cultural artifacts like music, films, and books. It might define the following set
3+
// of concrete types:
4+
5+
// Album
6+
// Book
7+
// Movie
8+
// Magazine
9+
// Podcast
10+
// TVEpisode
11+
// Track
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// We can express each abstraction of interest as an interface. Some properties are common to all
2+
// artifacts, such as a title, a creation date, and a list of creators (author s or artists).
3+
4+
import "time"
5+
6+
type Artifact interface {
7+
Title() string
8+
Creators() []string
9+
Created() time.Time
10+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Other properties are restricted to certain types of artifacts. Properties of the printed word are
2+
// relevant only to books and magazines, where as only movies and TV episodes have a screen
3+
// resolution.
4+
5+
import (
6+
"io"
7+
"time"
8+
)
9+
10+
type Text interface {
11+
Pages() int
12+
Words() int
13+
PageSize() int
14+
}
15+
16+
type Audio interface {
17+
Stream() (io.ReadCloser, error)
18+
RunningTime() time.Duration
19+
Format() string // e.g., "MP3", "WAV"
20+
}
21+
22+
type Video interface {
23+
Stream() (io.ReadCloser, error)
24+
RunningTime() time.Duration
25+
Format() string // e.g., "MP4", "WMV"
26+
Resolution() (x, y int)
27+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// These interfaces are but one useful way to group related concrete types together and express
2+
// the facets they share in common. We may discover other groupings later. For example, if we
3+
// find we need to handle Audio and Video items in the same way, we can define a Streamer
4+
// interface to represent their common asects without changing any existing type declarations.
5+
6+
import (
7+
"io"
8+
"time"
9+
)
10+
11+
type Streamer interface {
12+
Stream() (io.ReadCloser, error)
13+
RunningTime() time.Duration
14+
Format() string
15+
}
16+
17+
// Each grouping of concrete types based on their shared behaviors can be expressed as an interface type. Unlike class-based languages, in which the set of interfaces satisfied by a class is
18+
// explicit, in Go we can define new abstractions or groupings of interest when we need them,
19+
// without modifying the declaration of the concrete type. This is particularly useful when the
20+
// concrete type comes from a package written by a different author. Of course, there do need to
21+
// be underlying commonalities in the concrete types.

216-Interface-Satisfaction/interface-satisfy.gop

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)