From 56c9b51b937cca7d3db517add96bd9517bbffb80 Mon Sep 17 00:00:00 2001
From: Robert Griesemer
-A type determines the set of values and operations specific to values of that
-type. Types may be named or unnamed. Named types are specified
-by a (possibly qualified)
-type name; unnamed types are specified
-using a type literal, which composes a new type from existing types.
+A type determines a set of values together with operations and methods specific
+to those values. A type may be denoted by a type name, if it has one,
+or specified using a type literal, which composes a type from existing types.
Named instances of the boolean, numeric, and string types are
predeclared.
+Other named types are introduced with type declarations.
Composite types—array, struct, pointer, function,
interface, slice, map, and channel types—may be constructed using
type literals.
@@ -717,16 +716,23 @@ is the underlying type of the type to which
-The underlying type of Types
@@ -702,6 +700,7 @@ TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType
T
refers in its
- type T1 string
- type T2 T1
- type T3 []T1
- type T4 T3
+type (
+ A1 = string
+ A2 = A1
+)
+
+type (
+ B1 string
+ B2 B1
+ B3 []B1
+ B4 B3
+)
string
, T1
, and T2
-is string
. The underlying type of []T1
, T3
,
-and T4
is []T1
.
+The underlying type of string
, A1
, A2
, B1
,
+and B2
is string
.
+The underlying type of []B1
, B3
, and B4
is []B1
.
Method sets
@@ -1417,11 +1423,10 @@ Two types are either identical or different.
-Two named types are identical if their type names originate in the same -TypeSpec. -A named and an unnamed type are always different. Two unnamed types are identical -if the corresponding type literals are identical, that is, if they have the same -literal structure and corresponding components have identical types. In detail: +A defined type is always different from any other type. +Otherwise, two types are identical if their underlying type literals are +structurally equivalent; that is, they have the same literal structure and corresponding +components have identical types. In detail:
type ( - T0 []string - T1 []string - T2 struct{ a, b int } - T3 struct{ a, c int } - T4 func(int, float64) *T0 - T5 func(x int, y float64) *[]string + A0 = []string + A1 = A0 + A2 = struct{ a, b int } + A3 = int + A4 = func(A3, float64) *A0 + A5 = func(x int, _ float64) *[]string ) + +type ( + B0 A0 + B1 []string + B2 struct{ a, b int } + B3 struct{ a, c int } + B4 func(int, float64) *B0 + B5 func(x int, y float64) *A1 +) + +type C0 = B0
@@ -1474,17 +1490,22 @@ these types are identical:
-T0 and T0 +A0, A1, and []string +A2 and struct{ a, b int } +A3 and int +A4, func(int, float64) *[]string, and A5 + +B0, B0, and C0 []int and []int struct{ a, b *T5 } and struct{ a, b *T5 } -func(x int, y float64) *[]string and func(int, float64) (result *[]string) +func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
-T0
and T1
are different because they are named types
-with distinct declarations; func(int, float64) *T0
and
-func(x int, y float64) *[]string
are different because T0
-is different from []string
.
+B0
and B1
are different because they are new types
+created by distinct type definitions;
+func(int, float64) *B0
and func(x int, y float64) *[]string
+are different because B0
is different from []string
.
x
is assignable to a variable
x
's type V
and T
have identical
underlying types and at least one of V
-or T
is not a named type.
+or T
is not a defined type.
T
is an interface type and
@@ -1511,7 +1532,7 @@ or T
is not a named type.
x
is a bidirectional channel value, T
is a channel type,
x
's type V
and T
have identical element types,
-and at least one of V
or T
is not a named type.
+and at least one of V
or T
is not a defined type.
x
is the predeclared identifier nil
and T
@@ -1840,23 +1861,60 @@ last non-empty expression list.
-A type declaration binds an identifier, the type name, to a new type -that has the same underlying type as an existing type, -and operations defined for the existing type are also defined for the new type. -The new type is different from the existing type. +A type declaration binds an identifier, the type name, to a type. +Type declarations come in two forms: Alias declarations and type definitions. +
+ +
+TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) . +TypeSpec = AliasDecl | TypeDef . ++ +
+An alias declaration binds an identifier to the given type.
-TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) . -TypeSpec = identifier Type . +AliasDecl = identifier "=" Type .-
-type IntArray [16]int ++Within the scope of +the identifier, it serves as an alias for the type. +
+type ( - Point struct{ x, y float64 } - Polar Point + nodeList = []*Node // nodeList and []*Node are identical types + Polar = polar // Polar and polar denote identical types +) ++ + +Type definitions
+ ++A type definition binds an identifier to a newly created type +with the same underlying type and +operations as the given type. +
+ ++TypeDef = identifier Type . ++ ++The new type is called a defined type. +It is different from any other type, +including the type it is created from. +
+ ++type ( + Point struct{ x, y float64 } // Point and struct{ x, y float64 } are different types + polar Point // polar and Point denote different types ) type TreeNode struct { @@ -1872,8 +1930,9 @@ type Block interface {-The declared type does not inherit any methods -bound to the existing type, but the method set +A defined type may have methods associated with it. +It does not inherit any methods bound to the given type, +but the method set of an interface type or of elements of a composite type remains unchanged:
@@ -1901,8 +1960,8 @@ type MyBlock Block
-A type declaration may be used to define a different boolean, numeric, or string -type and attach methods to it: +Type definitions may be used to define different boolean, numeric, +or string types and associate methods with them:
@@ -1924,8 +1983,8 @@ func (tz TimeZone) String() string {Variable declarations
-A variable declaration creates one or more variables, binds corresponding -identifiers to them, and gives each a type and an initial value. +A variable declaration creates one or more variables, +binds corresponding identifiers to them, and gives each a type and an initial value.
@@ -2083,8 +2142,8 @@ and associates the method with the receiver's base type.-MethodDecl = "func" Receiver MethodName ( Function | Signature ) . -Receiver = Parameters . +MethodDecl = "func" Receiver MethodName ( Function | Signature ) . +Receiver = Parameters .@@ -2093,7 +2152,7 @@ name. That parameter section must declare a single non-variadic parameter, the r Its type must be of the form
T
or*T
(possibly using parentheses) whereT
is a type name. The type denoted byT
is called the receiver base type; it must not be a pointer or interface type and -it must be declared in the same package as the method. +it must be defined in the same package as the method. The method is said to be bound to the base type and the method name is visible only within selectors for typeT
or*T
.