forked from goinaction/code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlisting05.go
81 lines (62 loc) · 2.24 KB
/
listing05.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Sample program demonstrating when implicit interface conversions
// are provided by the compiler.
package main
import "fmt"
// =============================================================================
// Mover provides support for moving things.
type Mover interface {
Move()
}
// Locker provides support for locking and unlocking things.
type Locker interface {
Lock()
Unlock()
}
// MoveLocker provides support for moving and locking things.
type MoveLocker interface {
Mover
Locker
}
// =============================================================================
// bike represents a concrete type for the example.
type bike struct{}
// Move can change the position of a bike.
func (bike) Move() {
fmt.Println("Moving the bike")
}
// Lock prevents a bike from moving.
func (bike) Lock() {
fmt.Println("Locking the bike")
}
// Unlock allows a bike to be moved.
func (bike) Unlock() {
fmt.Println("Unlocking the bike")
}
// =============================================================================
func main() {
// Declare variables of the MoveLocker and Mover interfaces set to their
// zero value.
var ml MoveLocker
var m Mover
// Create a value of type bike and assign the value to the MoveLocker
// interface value.
ml = bike{}
// An interface value of type MoveLocker can be implicitly converted into
// a value of type Mover. They both declare a method named move.
m = ml
// prog.go:65: cannot use m (type Mover) as type MoveLocker in assignment:
// Mover does not implement MoveLocker (missing Lock method)
ml = m
// Interface type Mover does not declare methods named lock and unlock.
// Therefore, the compiler can't perform an implicit conversion to assign
// a value of interface type Mover to an interface value of type MoveLocker.
// It is irrelevant that the concrete type value of type bike that is stored
// inside of the Mover interface value implements the MoveLocker interface.
// We can perform a type assertion at runtime to support the assignment.
// Perform a type assertion against the Mover interface value to access
// a COPY of the concrete type value of type bike that was stored inside
// of it. Then assign the COPY of the concrete type to the MoveLocker
// interface.
b := m.(bike)
ml = b
}