-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #57 from tsingbx/interface-values
add doc for interface values
- Loading branch information
Showing
4 changed files
with
78 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// The value of the interface type and the interface value are two different concepts. | ||
|
||
// Go+ is a statically typed programming language, types are a compile time concept, so a type is not a value. | ||
// The value of the type descriptor provides information about each type, such as its name and methods. | ||
// In an interface value, the type component is represented by the appropriate type descriptor. | ||
|
||
// In Go+, interfaces variables are always initialize well-defined value as other type variables. | ||
// The zero value for an interface has both its type and value components set to nil, for example: | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"os" | ||
) | ||
|
||
var w io.Writer | ||
|
||
println w == nil | ||
|
||
var w2 io.Writer = os.Stdout | ||
|
||
w2 = nil // same as w, both w and w2 interface variable has zero value | ||
|
||
println w2 == nil | ||
|
||
var r *bytes.Reader | ||
|
||
println r == nil | ||
|
||
var r2 io.Reader = r // r2 has non-zero interface value. Its dynamic type is *bytes.Reader and its dynamic value is nil. So the result of r2 == nil is false | ||
|
||
if r2 != nil { | ||
slice := []byte{} | ||
r2.Read(slice) // panic: runtime error: invalid memory address or nil pointer dereference | ||
} | ||
|
||
// The interface variable w has zero value. So both its dynamic type and its dynamic value are nil. In this case, the result of if w == nil is true. | ||
// The interface variable r2 has non-zero value. Its dynamic type is *bytes.Reader and its dynamic value is nil. So the result of r2 == nil is false. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Interface values may be compared using == and !=. Two interface values are equal if both are | ||
// nil, or if their dynamic types are identical and their dynamic values are equal according to the | ||
// usual behavior of == for that type. Because interface values are comparable, they may be used | ||
// as the keys of a map or as the operand of a switch statement. | ||
|
||
// However, if two interface values are compared and have the same dynamic type, but that type | ||
// is not comparable (a slice, for instance), then the comparison fails with a panic. For example | ||
|
||
var x = []any{1, 2, 3} | ||
var y = []any{1, 2, 3} | ||
|
||
println(x == y) // panic: comparing uncomparable type []int | ||
|
||
// In this respect, interface types are unusual. Other types are either safely comparable (like | ||
// basic types and pointers) or not comparable at all (like slices, maps, and functions), but when | ||
// comparing interface values or aggregate types that contain interface values, we must be aware | ||
// of the potential for a panic. A similar risk exists when using interfaces as map keys or switch | ||
// operands. Only compare interface values if you are certain that they contain dynamic values | ||
// of comparable types. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// When handling errors, or during debugging, it is often helpful to report the dynamic type of | ||
// an interface value. For that, we use the fmt package’s %T verb: | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"os" | ||
) | ||
|
||
var w io.Writer | ||
|
||
fmt.printf "%T\n", w // "<nil>" | ||
|
||
w = os.Stdout | ||
fmt.printf "%T\n", w // "*os.File" | ||
|
||
w = new(bytes.Buffer) | ||
fmt.printf "%T\n", w // "*bytes.Buffer" | ||
|
||
// Internally, fmt uses reflection to obtain the name of the int erface’s dynamic type. |
This file was deleted.
Oops, something went wrong.