Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 1401] ファイルの概要

このコミットは、Go言語の初期設計における型システム、特に動的なコレクションの扱いに関する重要な変更を反映しています。従来の「オープン配列 (open arrays)」という概念を廃止し、より明確で強力な「スライス型 (slice types)」を導入しています。これにより、配列、マップ、チャネルといった複合型のセマンティクスが再定義され、Go言語のデータ構造の基盤が固められました。

コミット

commit a329471ced905effe0282e011a668bdc5779b0f1
Author: Robert Griesemer <gri@golang.org>
Date:   Mon Jan 5 11:17:26 2009 -0800

    A first attempt to capture the type changes.
    
    Instead of trying to make open arrays look like arrays (which they aren't,
    they just look like them), I decided to call them "slice types". As a result
    they have value semantics, and one can really talk about what they really are.
    
    Note:
    - There are lots of missing details
    - There are probably lots of mistakes
    
    Looking for some initial feedback.
    
    R=r
    DELTA=444  (180 added, 189 deleted, 75 changed)
    OCL=21769
    CL=22020
---
 doc/go_spec.txt | 509 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 250 insertions(+), 259 deletions(-)

diff --git a/doc/go_spec.txt b/doc/go_spec.txt
index a3af04af3a..db9c51764c 100644
--- a/doc/go_spec.txt
+++ b/doc/go_spec.txt
@@ -3,7 +3,7 @@ The Go Programming Language Specification (DRAFT)
 
 Robert Griesemer, Rob Pike, Ken Thompson
 
-(December 18, 2008)
+(January 5, 2009)
 
 ----
 
@@ -45,6 +45,9 @@ Todo's:
  doesn't correspond to the implementation. The spec is wrong when it
  comes to the first index i: it should allow (at least) the range 0 <= i <= len(a).
  also: document different semantics for strings and arrays (strings cannot be grown).
+[ ] new as it is now is weird - need to go back to previous semantics and introduce
+    literals for slices, maps, channels
+[ ] determine if really necessary to disallow array assignment
 
 
 Open issues:
@@ -167,10 +170,11 @@ Contents
  Array types
  Struct types
  Pointer types
- Map types
- Channel types
  Function types
  Interface types
+ Slice types
+ Map types
+ Channel types
  Type equality
 
  Expressions
@@ -337,11 +341,22 @@ they are no longer accessible.  There is no pointer arithmetic in Go.
 Values and references
 ----
 
-All objects have value semantics, but their contents may be accessed
-through different pointers referring to the same object.
-For example, when calling a function with an array, the array is
-passed by value, possibly by making a copy.   To pass a reference,
-one must explicitly pass a pointer to the array.
+TODO
+- revisit this section
+- if we'd keep the * for maps and chans, all types would have value semantics
+  again
+
+Most data types have value semantics, but their contents may be accessed
+through different pointers referring to the same object. However, some
+data types have reference semantics to facilitate common usage patterns
+and implementation.
+
+For example, when calling a function with a struct, the struct is passed
+by value, possibly by making a copy. To pass a reference, one must explicitly
+pass a pointer to the struct. On the other hand, when calling a function with
+a map, a reference to the map is passed implicitly without the need to pass a
+pointer to the map; thus the map contents are not copied when a map is assigned
+to a variable.
 
 
 Multithreading and channels
@@ -1046,27 +1061,31 @@ Types
 A type specifies the set of values that variables of that type may assume
 and the operators that are applicable.
 
-A type may be specified by a type name (§Type declarations)
-or a type literal.
+A type may be specified by a type name (§Type declarations) or a type literal.
+A type literal is a syntactic construct that explicitly specifies the
+composition of a new type in terms of other (already declared) types.
 
  Type = TypeName | TypeLit .
  TypeName = QualifiedIdent.
  TypeLit =
- ArrayType | StructType | PointerType | FunctionType |
- ChannelType | MapType | InterfaceType .
-
-There are basic types and composite types. Basic types are predeclared and
-denoted by their type names.
-Composite types are arrays, maps, channels, structures, functions, pointers,
-and interfaces. They are constructed from other (basic or composite) types
-and denoted by their type names or by type literals.
-
-Types may ``complete'' or ''incomplete''. Basic, pointer, function and
-interface types are always complete (although their components, such
-as the base type of a pointer type, may be incomplete). All other types are
-complete when they are fully declared. Incomplete types are subject to
-usage restrictions; for instance the type of a variable must be complete
-where the variable is declared.
+ ArrayType | StructType | PointerType | FunctionType | InterfaceType |
+ SliceType | MapType | ChannelType .
+
+Some types are predeclared and denoted by their type names; these are called
+``basic types''. Generally (except for strings) they are not composed of more
+elementary types; instead they model elementary machine data types.
+
+All other types are called ``composite types''; they are composed from other
+(basic or composite) types and denoted by their type names or by type literals.
+There are arrays, structs, pointers, functions, interfaces, slices, maps, and
+channels.
+
+At a given point in the source code, a type may be ``complete'' or
+''incomplete''. Array and struct types are complete when they are fully declared.
+All other types are always complete (although their components, such as the base
+type of a pointer type, may be incomplete). Incomplete types are subject to usage
+restrictions; for instance the type of a variable must be complete where the
+variable is declared.
 
  CompleteType = Type .
 
@@ -1076,11 +1095,6 @@ of the pointer base type (§Pointer types). All types have an interface;
 if they have no methods associated with them, their interface is
 called the ``empty'' interface.
 
-TODO: Since methods are added one at a time, the interface of a type may
-be different at different points in the source text. Thus, static checking
-may give different results then dynamic checking which is problematic.
-Need to resolve.
-
 The ``static type'' (or simply ``type'') of a variable is the type defined by
 the variable's declaration. The ``dynamic type'' of a variable is the actual
 type of the value stored in a variable at run-time. Except for variables of
@@ -1144,10 +1158,10 @@ convenience:
 For instance, int might have the same size as int32 on a 32-bit
 architecture, or int64 on a 64-bit architecture.
 
-Except for byte, which is an alias for uint8, all numeric types
+Except for "byte", which is an alias for "uint8", all numeric types
 are different from each other to avoid portability issues. Conversions
 are required when different numeric types are mixed in an expression or assignment.
-For instance, int32 and int are not the same type even though they may have
+For instance, "int32" and "int" are not the same type even though they may have
 the same size on a particular platform.
 
 
@@ -1161,7 +1175,7 @@ available through the two predeclared constants, "true" and "false".
 Strings
 ----
 
-The string type represents the set of string values (strings).
+The "string" type represents the set of string values (strings).
 Strings behave like arrays of bytes, with the following properties:
 
 - They are immutable: after creation, it is not possible to change the
@@ -1188,133 +1202,36 @@ just array of bytes) by a conversion (§Conversions):
 Array types
 ----
 
-An array is a composite type consisting of a number of elements all of the same
-type, called the element type. The number of elements of an array is called its
-length; it is always positive (including zero).  The elements of an array are
-designated by indices which are integers between 0 and the length - 1.
-
-An array type specifies the array element type and an optional array
-length which must be a compile-time constant expression of a (signed or
-unsigned) int type. If present, the array length and its value is part of
-the array type. The element type must be a complete type (§Types).
-
-If the length is present in the declaration, the array is called
-``fixed array''; if the length is absent, the array is called ``open array''.
+An array is a composite type consisting of a number of elements all of the
+same type, called the element type. The element type must be a complete type
+(§Types). The number of elements of an array is called its length; it is never
+negative. The elements of an array are designated by indices
+which are integers from 0 through the length - 1.
 
-\tArrayType = "[" [ ArrayLength ] "]" ElementType .
+\tArrayType = "[" ArrayLength "]" ElementType .
 \tArrayLength = Expression .
 \tElementType = CompleteType .
 
-The length of an array "a" can be discovered using the built-in function
+The array length and its value are part of the array type. The array length
+must be a constant expression (§Constant expressions) that evaluates to an
+integer value >= 0.
 
-\tlen(a)
-\t
-If "a" is a fixed array, the length is known at compile-time and "len(a)" can
-be evaluated to a compile-time constant. If "a" is an open array, then "len(a)"
-will only be known at run-time.
-
-The amount of space actually allocated to hold the array data may be larger
-then the current array length; this maximum array length is called the array
-capacity. The capacity of an array "a" can be discovered using the built-in
+The number of elements of an array "a" can be discovered using the built-in
 function
 
-\tcap(a)
-\t
-and the following relationship between "len()" and "cap()" holds:
-
-\t0 <= len(a) <= cap(a)
-
-Allocation: An open array may only be used as a function parameter type, or
-as element type of a pointer type. There are no other variables
-(besides parameters), struct or map fields of open array type; they must be
-pointers to open arrays. For instance, an open array may have a fixed array
-element type, but a fixed array must not have an open array element type
-(though it may have a pointer to an open array). Thus, for now, there are
-only ``one-dimensional'' open arrays.
+\tlen(a)
 
-The following are legal array types:
+The length of arrays is known at compile-time, and the result of a call to
+"len(a)" is a compile-time constant.
 
-\t[32] byte
+\t[32]byte
  [2*N] struct { x, y int32 }
-\t[1000]*[] float64
-\t[] int
-\t[][1024] byte
-\t
-Variables of fixed arrays may be declared statically:
-
-\tvar a [32] byte
-\tvar m [1000]*[] float64
-
-Static and dynamic arrays may be allocated dynamically via the built-in function
-"new()" which takes an array type and zero or one array lengths as parameters,
-depending on the number of open arrays in the type:
-
-\tnew([32] byte)                // *[32] byte
-\tnew([]int, 100);              // *[100] int
-\tnew([][1024] byte, 4);        // *[4][1024] byte
-
-Assignment compatibility: Fixed arrays are assignment compatible to variables
-of the same type, or to open arrays with the same element type. Open arrays
-may only be assigned to other open arrays with the same element type.
-
-For the variables:
-
-\tvar fa, fb [32] int
-\tvar fc [64] int
-\tvar pa, pb *[] int
-\tvar pc *[][32] int
-
-the following assignments are legal, and cause the respective array elements
-to be copied:
-
-\tfa = fb;
-\tpa = pb;
-\t*pa = *pb;
-\tfa = *pc[7];
-\t*pa = fa;
-\t*pb = fc;
-\t*pa = *pc[11];
-
-The following assignments are illegal:
-
-\tfa = *pa;      // cannot assign open array to fixed array
-\t*pc[7] = *pa;  // cannot assign open array to fixed array
-\tfa = fc;       // different fixed array types
-\t*pa = *pc;     // different element types of open arrays
-
-
-Array indexing: Given a (pointer to an) array variable "a", an array element
-is specified with an array index operation:
-
-\ta[i]
-\t
-This selects the array element at index "i". "i" must be within array bounds,
-that is "0 <= i < len(a)".
-
-Array slicing: Given a (pointer to an) array variable "a", a sub-array is
-specified with an array slice operation:
-
-\ta[i : j]
-\t
-This selects the sub-array consisting of the elements "a[i]" through "a[j - 1]"
-(exclusive "a[j]"). "i" must be within array bounds, and "j" must satisfy
-"i <= j <= cap(a)". The length of the new slice is "j - i". The capacity of
-the slice is "cap(a) - i"; thus if "i" is 0, the array capacity does not change
-as a result of a slice operation. An array slice is always an open array.
-
-Note that a slice operation does not ``crop'' the underlying array, it only
-provides a new ``view'' to an array. If the capacity of an array is larger
-then its length, slicing can be used to ``grow'' an array:
+\t[1000]*float64
 
-\t// allocate an open array of bytes with length i and capacity 100
-\ti := 10;
-\ta := new([] byte, 100) [0 : i];
-\t// grow the array by n bytes, with i + n <= 100
-\ta = a[0 : i + n];
-\n-\n-TODO: Expand on details of slicing and assignment, especially between pointers
-- to arrays and arrays.
+Assignment compatibility: Arrays can be assigned to slice variables of
+equal element type; arrays cannot be assigned to other array variables
+or passed to functions (by value).
+TODO rethink this restriction. Causes irregularities.
 
 
 Struct types
@@ -1407,7 +1324,7 @@ type, called the ``base type'' of the pointer, and the value "nil".
 \tBaseType = Type .
 
 \t*int
-\t*map[string] *chan
+\tmap[string] chan
 
 The pointer base type may be denoted by an identifier referring to an
 incomplete type (§Types), possibly declared via a forward declaration.
@@ -1426,68 +1343,6 @@ of pointer type, only if both types are equal.
 Pointer arithmetic of any kind is not permitted.
 
 
--Map types
-----
-
-A map is a composite type consisting of a variable number of entries
-called (key, value) pairs. For a given map, the keys and values must
-each be of a specific complete type (§Types) called the key and value type,
-respectively. Upon creation, a map is empty and values may be added and removed
-during execution.  The number of entries in a map is called its length.
-
-\tMapType = "map" "[" KeyType "]" ValueType .
-\tKeyType = CompleteType .
-\tValueType = CompleteType .
-
-\tmap [string] int
-\tmap [struct { pid int; name string }] *chan Buffer
-\tmap [string] any
-
-The length of a map "m" can be discovered using the built-in function
-
-\tlen(m)
-
-Allocation: A map may only be used as a base type of a pointer type.
-There are no variables, parameters, array, struct, or map fields of
-map type, only of pointers to maps.
-
-Assignment compatibility: A pointer to a map type is assignment
-compatible to a variable of pointer to map type only if both types
-are equal.
-
-
-Channel types
-----
-
-A channel provides a mechanism for two concurrently executing functions
-to synchronize execution and exchange values of a specified type. This
-type must be a complete type (§Types).
-
-Upon creation, a channel can be used both to send and to receive.
-By conversion or assignment, a channel may be constrained only to send or
-to receive. This constraint is called a channel's ``direction''; either
-bi-directional (unconstrained), send, or receive.
-
-\tChannelType = Channel | SendChannel | RecvChannel .
-\tChannel = "chan" ValueType .
-\tSendChannel = "chan" "<-" ValueType .
-\tRecvChannel = "<-" "chan" ValueType .
-
-\tchan T         // can send and receive values of type T
-\tchan <- float  // can only be used to send floats
-\t<-chan int     // can receive only ints
-
-Channel variables always have type pointer to channel.
-It is an error to attempt to use a channel value and in
-particular to dereference a channel pointer.
-
-\tvar ch *chan int;
-\tch = new(chan int);  // new returns type *chan int
-
-TODO(gri): Do we need the channel conversion? It's enough to just keep
-the assignment rule.
-
-
 Function types
 ----
 
@@ -1540,7 +1395,7 @@ the set of methods specified by the interface type, and the value "nil".
 \tMethodSpecList = MethodSpec { ";" MethodSpec } [ ";" ] .
 \tMethodSpec = IdentifierList FunctionType .
 
-\t// A basic file interface.
+\t// An interface specifying a basic File type.
 \tinterface {
  Read, Write (b Buffer) bool;
  Close ();
@@ -1593,6 +1448,148 @@ Assignment compatibility: A value can be assigned to an interface variable
 if the static type of the value implements the interface or if the value is "nil".
 
 
+Slice types
+----
+
+An (array) slice type denotes the set of all slices (segments) of arrays
+(§Array types) of a given element type, and the value "nil".
+The number of elements of a slice is called its length; it is never negative.
+The elements of a slice are designated by indices which are
+integers from 0 through the length - 1.
+
+\tSliceType = "[" "]" ElementType .
+
+Syntactically and semantically, arrays and slices look and behave very
+similarly, but with one important difference: A slice is a descriptor
+of an array segment; in particular, different variables of a slice type may
+refer to different (and possibly overlapping) segments of the same underlying
+array. Thus, with respect to the underlying array, slices behave like
+references. In contrast, two different variables of array type always
+denote two different arrays.
+
+For slices, the actual array underlying the slice may extend past the current
+slice length; the maximum length a slice may assume is called its capacity.
+The capacity of any slice "a" can be discovered using the built-in function
+
+\tcap(a)
+
+and the following relationship between "len()" and "cap()" holds:
+
+\t0 <= len(a) <= cap(a)
+
+The value of an uninitialized slice is "nil", and its length and capacity
+are 0. A new, initialized slice value for a given elemen type T is
+created using the built-in function "new", which takes a slice type
+and parameters specifying the length and optionally the capacity:
+
+\tnew([]T, length)
+\tnew([]T, length, capacity)
+
+Assignment compatibility: Slices are assignment compatible to variables
+of the same type.
+
+Indexing: Given a (pointer to) a slice variable "a", a slice element is
+specified with an index operation:
+
+\ta[i]
+
+This denotes the slice element at index "i". "i" must be within bounds,
+that is "0 <= i < len(a)".
+
+Slicing: Given a a slice variable "a", a sub-slice is created with a slice
+operation:
+
+\ta[i : j]
+
+This creates the sub-slice consisting of the elements "a[i]" through "a[j - 1]"
+(that is, excluding "a[j]"). "i" must be within array bounds, and "j" must satisfy
+"i <= j <= cap(a)". The length of the new slice is "j - i". The capacity of
+the slice is "cap(a) - i"; thus if "i" is 0, the slice capacity does not change
+as a result of a slice operation. The type of a sub-slice is the same as the
+type of the slice.
+
+TODO what are the proper restrictions on slices?
+TODO describe equality checking against nil
+
+
+Map types
+----
+
+A map is a composite type consisting of a variable number of entries
+called (key, value) pairs. For a given map, the keys and values must
+each be of a specific complete type (§Types) called the key and value type,
+respectively. The number of entries in a map is called its length; it is never
+negative.
+
+\tMapType = "map" "[" KeyType "]" ValueType .
+\tKeyType = CompleteType .
+\tValueType = CompleteType .
+
+Upon creation, a map is empty and values may be added and removed
+during execution.
+
+\tmap [string] int
+\tmap [struct { pid int; name string }] chan Buffer
+\tmap [string] interface {}
+
+The length of a map "m" can be discovered using the built-in function
+
+\tlen(m)
+
+The value of an uninitialized map is "nil". A new, initialized map
+value for given key and value types K and V is created using the built-in
+function "new" which takes the map type and an (optional) capacity as arguments:
+
+\tmy_map := new(map[K] V, 100);
+
+The map capacity is an allocation hint for more efficient incremental growth
+of the map.
+
+Assignment compatibility: A map type is assignment compatible to a variable of
+map type only if both types are equal.
+
+TODO: Comparison against nil
+
+
+Channel types
+----
+
+A channel provides a mechanism for two concurrently executing functions
+to synchronize execution and exchange values of a specified type. This
+type must be a complete type (§Types). (TODO could it be incomplete?)
+
+\tChannelType = Channel | SendChannel | RecvChannel .
+\tChannel = "chan" ValueType .
+\tSendChannel = "chan" "<-" ValueType .
+\tRecvChannel = "<-" "chan" ValueType .
+
+Upon creation, a channel can be used both to send and to receive.
+By conversion or assignment, a channel may be constrained only to send or
+to receive. This constraint is called a channel's ``direction''; either
+bi-directional (unconstrained), send, or receive.
+
+\tchan T         // can send and receive values of type T
+\tchan <- float  // can only be used to send floats
+\t<-chan int     // can only receive ints
+
+The value of an uninitialized channel is "nil". A new, initialized channel
+value for a given element type T is created using the built-in function "new",
+which takes the channel type and an (optional) capacity as arguments:
+
+\tmy_chan = new(chan int, 100);
+
+The capacity sets the size of the buffer in the communication channel. If the
+capacity is greater than zero, the channel is asynchronous and, provided the
+buffer is not full, sends can succeed without blocking. If the capacity is zero,
+the communication succeeds only when both a sender and receiver are ready.
+
+Assignment compatibility:
+TODO write this paragraph
+
+TODO(gri): Do we need the channel conversion? It's enough to just keep
+the assignment rule.
+
+
 Type equality
 ----
 
@@ -1612,8 +1609,7 @@ speaking, two types are equal if their values have the same layout in memory.
 More precisely:
 
 \t- Two array types are equal if they have equal element types and if they
-\t  are either fixed arrays with the same array length, or they are open
-\t  arrays.
+\t  have the same array length.
 
 \t- Two struct types are equal if they have the same number of fields in the
 \t  same order, corresponding fields are either both named or both anonymous,
@@ -1627,6 +1623,8 @@ More precisely:
 \t  equal (a "..." parameter is equal to another "..." parameter).
 \t  Note that parameter and result names do not have to match.
 
+\t- Two slice types are equal if they have equal element types.
+\n
 \t- Two channel types are equal if they have equal value types and
 \t  the same direction.
 
@@ -1645,8 +1643,7 @@ same literal structure and corresponding components have identical types.
 More precisely:
 
 \t- Two array types are identical if they have identical element types and if
-\t  they are either fixed arrays with the same array length, or they are open
-\t  arrays.
+\t  they have the same array length.
 
 \t- Two struct types are identical if they have the same number of fields in
 \t  the same order, corresponding fields either have both the same name or
@@ -1659,6 +1656,8 @@ More precisely:
 \t  if corresponding parameter and result types are identical (a "..."
 \t  parameter is identical to another "..." parameter with the same name).
 
+\t- Two slice types are identical if they have identical element types.
+\n
 \t- Two channel types are identical if they have identical value types and
 \t  the same direction.
 
@@ -1725,7 +1724,7 @@ Thus, the values 991, 42.0, and 1e9 are ok, but -1, 3.14, or 1e100 are not.\n <!--\n TODO(gri) This may be overly constraining. What about "len(a) + c" where\n c is an ideal number? Is len(a) of type int, or of an ideal number? Probably\n-should be ideal number, because for fixed arrays, it is a constant.\n+should be ideal number, because for arrays, it is a constant.\n -->\n \n \n@@ -1779,8 +1778,6 @@ Composite literals are values of the type specified by LiteralType; that is\n a new value is created every time the literal is evaluated. To get\n a pointer to the literal, the address operator "&" must be used.\n \n-Implementation restriction: Currently, map literals are pointers to maps.\n-\n Given\n \n \ttype Rat struct { num, den int };\n@@ -1791,22 +1788,23 @@ one can write\n \tpi := Num{Rat{22, 7}, 3.14159, "pi"};\n \n \n-Array literals are always fixed arrays: If no array length is specified in\n-LiteralType, the array length is the number of elements provided in the composite\n-literal. Otherwise the array length is the length specified in LiteralType.\n-In the latter case, fewer elements than the array length may be provided in the\n-literal, and the missing elements are set to the appropriate zero value for\n-the array element type. It is an error to provide more elements then specified\n-in LiteralType.\n+TODO section below needs to be brought into agreement with 6g.\n+\n+The length of an array literal is the length specified in the LiteralType.\n+If fewer elements than the length are provided in the literal, the missing\n+elements are set to the appropriate zero value for the array element type.\n+It is an error to provide more elements than specified in LiteralType.\n+If no length is specified, the length is the number of elements provided\n+in the literal.\n \n \tbuffer := [10]string{};  // len(buffer) == 10\n-\tprimes := [6]int{2, 3, 5, 7, 9, 11};  // len(primes) == 6\n+\tprimes := &[6]int{2, 3, 5, 7, 9, 11};  // len(primes) == 6\n \tweekenddays := &[]string{"sat", "sun"};  // len(weekenddays) == 2\n \n Map literals are similar except the elements of the expression list are\n key-value pairs separated by a colon:\n \n-\tm := &map[string]int{"good": 0, "bad": 1, "indifferent": 7};\n+\tm := map[string]int{"good": 0, "bad": 1, "indifferent": 7};\n \n TODO: Consider adding helper syntax for nested composites\n (avoids repeating types but complicates the spec needlessly.)\n@@ -1830,7 +1828,7 @@ A function literal can be assigned to a variable of the\n corresponding function pointer type, or invoked directly.\n \n \tf := func(x, y int) { return x + y; }\n-\tfunc(ch *chan int) { ch <- ACK; } (reply_chan)\n+\tfunc(ch chan int) { ch <- ACK; } (reply_chan)\n \n Implementation restriction: A function literal can reference only\n its parameters, global variables, and variables declared within the\n@@ -1860,7 +1858,6 @@ Primary expressions\n \t(s + ".txt")\n \tf(3.1415, true)\n \tPoint(1, 2)\n-\tnew([]int, 100)\n \tm["foo"]\n \ts[i : j + 1]\n \tobj.color\n@@ -2292,7 +2289,8 @@ Comparison operators\n \n Comparison operators yield a boolean result. All comparison operators apply\n to strings and numeric types. The operators "==" and "!=" also apply to\n-boolean values, pointer and interface types (including the value "nil").\n+boolean values, pointer, interface types, slice, map, and channel types\n+(including the value "nil").\n \n \t==    equal\n \t!=    not equal\n@@ -2312,6 +2310,11 @@ been modified since creation (§Program initialization and execution).\n \n TODO: Should we allow general comparison via interfaces? Problematic.\n \n+Slices, maps, and channels are equal if they denote the same slice, map, or\n+channel respectively, or are "nil".\n+\n+TODO: We need to be more precise here.\n+\n \n Logical operators\n ----\n@@ -2403,7 +2406,7 @@ Communication operators\n The syntax presented above covers communication operations.  This\n section describes their form and function.\n \n-Here the term "channel" means "variable of type *chan".\n+Here the term "channel" means "variable of type chan".\n \n A channel is created by allocating it:\n \n@@ -2477,7 +2480,7 @@ A constant expression is an expression whose operands are all constants\n (§Constants). Additionally, the result of the predeclared functions\n below (with appropriate arguments) is also constant:\n \n-\tlen(a)\t\tif a is a fixed array\n+\tlen(a)\t\tif a is an array (as opposed to an array slice)\n \n TODO: Complete this list as needed.\n \n@@ -2867,7 +2870,7 @@ scope of such variables begins immediately after the variable identifier\n and ends at the end of the respective "select" case (that is, before the\n next "case", "default", or closing brace).\n \n-\tvar c, c1, c2 *chan int;\n+\tvar c, c1, c2 chan int;\n \tvar i1, i2 int;\n \tselect {\n \tcase i1 = <-c1:\n@@ -2885,7 +2888,7 @@ next "case", "default", or closing brace).\n \t\t}\n \t}\n \n-\tvar ca *chan interface {};\n+\tvar ca chan interface {};\n \tvar i int;\n \tvar f float;\n \tselect {\n@@ -3159,9 +3162,10 @@ Allocation\n ----\n \n The built-in function "new()" takes a type "T", optionally followed by a\n-type-specific list of expressions. It allocates memory for a variable\n-of type "T" and returns a pointer of type "*T" to that variable. The\n-memory is initialized as described in the section on initial values\n+type-specific list of expressions. It returns a value of type "T" (possibly\n+by allocating memory in the heap).\n+TODO describe initialization\n+The memory is initialized as described in the section on initial values\n (§Program initialization and execution).\n \n \tnew(type [, optional list of expressions])\n@@ -3169,7 +3173,7 @@ memory is initialized as described in the section on initial values\n For instance\n \n \ttype S struct { a int; b float }\n-\tnew(S)\n+\tnew(*S)\n \n dynamically allocates memory for a variable of type S, initializes it\n (a=0, b=0.0), and returns a value of type *S pointing to that variable.\n@@ -3177,24 +3181,11 @@ dynamically allocates memory for a variable of type S, initializes it\n The only defined parameters affect sizes for allocating arrays,\n buffered channels, and maps.\n \n-\tap := new([]int, 10);            # a pointer to an open array of 10 ints\n-\tc := new(chan int, 10);          # a pointer to a channel with a buffer size of 10\n-\tm := new(map[string] int, 100);  # a pointer to a map with initial space for 100 elements\n-\n-For arrays, a third argument may be provided to specify the array capacity:\n-\n-\tbp := new([]byte, 0, 1024);      # a pointer to an empty open array with capacity 1024\n+\ts := new([]int);\t\t\t\t # slice\n+\tc := new(chan int, 10);          # channel with a buffer size of 10\n+\tm := new(map[string] int, 100);  # map with initial space for 100 elements\n \n-<!--\n-TODO gri thinks that we should not use this notation to specify the capacity\n-for the following reasons: a) It precludes the future use of that argument as the length\n-for multi-dimensional open arrays (which we may need at some point) and b) the\n-effect of "new(T, l, c)" is trivially obtained via "new(T, c)[0 : l]", doesn't\n-require extra explanation, and leaves options open.\n-Finally, if there is a performance concern (the single new() may be faster\n-then the new() with slice, the compiler can trivially rewrite the slice version\n-into a faster internal call that doesn't do slicing).\n--->\n+TODO revisit this section\n \n \n ----\n@@ -3264,7 +3255,7 @@ Here is a complete example Go package that implements a concurrent prime sieve:\n \tpackage main\n \t\n \t// Send the sequence 2, 3, 4, ... to channel 'ch'.\n-\tfunc Generate(ch *chan <- int) {\n+\tfunc Generate(ch chan <- int) {\n \t\tfor i := 2; ; i++ {\n \t\t\tch <- i  // Send 'i' to channel 'ch'.\n \t\t}\n@@ -3272,7 +3263,7 @@ Here is a complete example Go package that implements a concurrent prime sieve:\n \t\n \t// Copy the values from channel 'in' to channel 'out',\n \t// removing those divisible by 'prime'.\n-\tfunc Filter(in *chan <- int, out *<-chan int, prime int) {\n+\tfunc Filter(in chan <- int, out *<-chan int, prime int) {\n \t\tfor {\n \t\t\ti := <-in;  // Receive value of new variable 'i' from 'in'.\n \t\t\tif i % prime != 0 {\n```

## GitHub上でのコミットページへのリンク

[https://github.com/golang/go/commit/a329471ced905effe0282e011a668bdc5779b0f1](https://github.com/golang/go/commit/a329471ced905effe0282e011a668bdc5779b0f1)

## 元コミット内容

このコミットは、Go言語の型システムにおける重要な変更、特に「オープン配列」の概念を「スライス型」に置き換える最初の試みを記述しています。コミットメッセージは、オープン配列が実際には配列ではないという認識から、それらを「スライス型」と呼ぶことで、より正確なセマンティクスと値セマンティクスを持つようにしたことを示唆しています。これは初期段階の変更であり、まだ多くの詳細が欠けており、間違いも含まれている可能性があると明記されています。

## 変更の背景

Go言語の初期設計において、可変長シーケンスを表現する方法として「オープン配列」という概念が存在しました。しかし、これは固定長である「配列」と混同されやすく、その振る舞いが直感的ではないという問題がありました。特に、オープン配列が参照セマンティクスを持つ一方で、Goの他の多くの型が値セマンティクスを持つという点で、一貫性に欠けていました。

このコミットの背景には、Go言語の設計者たちが、より明確で、Goの哲学に合致する動的コレクションのメカニズムを求めていたという経緯があります。固定長配列の限界を認識しつつ、より柔軟で動的なデータ構造を提供するために、スライスという概念が導入されました。スライスは、基盤となる配列への「ビュー」として機能し、動的なサイズ変更や効率的な部分配列の操作を可能にします。この変更は、Go言語が提供するデータ構造の使いやすさと堅牢性を向上させる上で不可欠なステップでした。

## 前提知識の解説

このコミットを理解するためには、以下のGo言語の基本的な概念と、当時の設計思想に関する知識が必要です。

*   **値セマンティクスと参照セマンティクス**:
    *   **値セマンティクス (Value Semantics)**: 変数に値を代入したり、関数に引数として渡したりする際に、値そのものがコピーされる挙動を指します。変更はコピーされた値に対して行われるため、元の値には影響しません。Go言語では、数値型、ブール型、構造体などが基本的に値セマンティクスを持ちます。
    *   **参照セマンティクス (Reference Semantics)**: 変数に値を代入したり、関数に引数として渡したりする際に、値そのものではなく、その値が格納されているメモリ上の場所(参照)がコピーされる挙動を指します。これにより、複数の変数が同じメモリ上のデータを指すことができ、いずれかの変数を通じてデータが変更されると、他の変数からもその変更が参照されます。ポインタが典型的な参照セマンティクスを持ちます。
*   **配列 (Arrays)**: Go言語における配列は、同じ型の要素を固定された数だけ格納するデータ構造です。配列の長さは型の一部であり、コンパイル時に決定されます。例えば、`[3]int` と `[4]int` は異なる型とみなされます。配列を別の変数に代入したり、関数に渡したりすると、その内容全体がコピーされます。
*   **オープン配列 (Open Arrays)**: このコミット以前に存在した概念で、長さが指定されていない配列のような型 (`[]T`) を指していました。これは、動的なサイズのコレクションを意図していましたが、そのセマンティクスが不明瞭であり、固定長配列との混同を招きやすかったため、このコミットで「スライス」に置き換えられました。
*   **`new` と `make` の違い (初期段階)**: Go言語にはメモリを割り当てるための組み込み関数 `new` と `make` があります。
    *   `new(T)`: 型 `T` のゼロ値を割り当て、その型へのポインタ `*T` を返します。
    *   `make(T, args)`: スライス、マップ、チャネルといった組み込みの参照型を初期化し、その型の値を返します。このコミット以前は、`new` がオープン配列、マップ、チャネルのポインタを返すような振る舞いも一部で想定されていましたが、このコミットでそのセマンティクスが明確化されます。
*   **Go言語の設計哲学**: Go言語は、シンプルさ、効率性、並行処理の容易さを重視しています。データ構造の設計においても、これらの原則が反映され、開発者が直感的に理解し、効率的に利用できるようなセマンティクスが追求されました。

## 技術的詳細

このコミットの技術的な核心は、Go言語の型システムにおける「オープン配列」の概念を完全に廃止し、より洗練された「スライス型」を導入した点にあります。これにより、配列、マップ、チャネルのセマンティクスが再定義され、Go言語のデータ構造の振る舞いがより一貫性のあるものになりました。

1.  **スライス型の導入と「オープン配列」の廃止**:
    *   以前は `[]T` のような構文が「オープン配列」として扱われていましたが、このコミット以降、これは「スライス型」として正式に定義されます。
    *   スライスは、基盤となる配列のセグメント(部分)を記述するデータ構造であり、ポインタ、長さ (length)、容量 (capacity) の3つの要素から構成されます。
    *   `len(s)` はスライスの現在の要素数を、`cap(s)` はスライスが参照する基盤配列の最大容量を返します。
    *   スライスは、基盤配列への参照のように振る舞いますが、スライス変数自体は値セマンティクスを持ちます。つまり、スライスを関数に渡す際や代入する際には、スライスのヘッダ情報(ポインタ、長さ、容量)がコピーされます。これにより、関数内でスライスの要素を変更すると、元のスライスも影響を受けますが、スライス自体の長さや容量を変更しても、元のスライス変数が指すヘッダは変更されません(新しいスライスが返される)。
    *   `new([]T, length)` や `new([]T, length, capacity)` のように、`new` 関数を使ってスライスを初期化できるようになりました。

2.  **配列の厳密な固定長化**:
    *   この変更により、Go言語の配列は常に固定長であることが明確になりました。配列の長さは型の一部であり、コンパイル時に決定される定数でなければなりません。
    *   `len(a)` は配列の長さを返し、これは常にコンパイル時定数となります。
    *   配列は、同じ要素型を持つスライス変数に代入できるようになりましたが、他の配列変数への代入や関数への値渡しは、型が完全に一致しない限り許可されません。

3.  **マップとチャネルのセマンティクス変更**:
    *   以前は、マップやチャネルはポインタを介してのみアクセスされるような記述があり、`new(map[K]V)` は `*map[K]V` を、`new(chan T)` は `*chan T` を返すような振る舞いが示唆されていました。
    *   このコミットにより、マップとチャネルもスライスと同様に、その型自体が値セマンティクスを持つように変更されました。つまり、`new(map[K]V)` は `map[K]V` を、`new(chan T)` は `chan T` を直接返します。
    *   しかし、これらの型が参照する基盤となるデータ構造(マップのエントリやチャネルのバッファ)は、暗黙的に参照セマンティクスを持ちます。これにより、複数の変数が同じマップやチャネルを参照し、いずれかの変数を通じて行われた変更が他の変数からも見えるようになります。

4.  **`new` 組み込み関数の再定義**:
    *   `new(T)` の振る舞いが再定義されました。以前は常に `*T` を返すとされていましたが、このコミット以降、スライス、マップ、チャネルに対しては `T` 型の値を直接返すようになりました。構造体などの他の型に対しては引き続き `*T` を返します。
    *   これは、スライス、マップ、チャネルが「ヘッダ」部分で値セマンティクスを持ち、そのヘッダが基盤となるデータ構造への参照を含むというGoの設計思想を反映しています。

5.  **型等価性 (Type Equality) と同一性 (Identity) の更新**:
    *   配列の型等価性および同一性のルールが更新され、固定長配列とオープン配列の区別がなくなったため、単純に要素型と長さが同じであれば等しい/同一であると定義されました。
    *   新たに導入されたスライス型についても、要素型が等しければ型が等しい/同一であると定義されました。

これらの変更は、Go言語のデータ構造のセマンティクスを大幅に簡素化し、開発者がより直感的にコードを記述できるようにするための重要なステップでした。特に、スライスの導入は、Goが動的なコレクションを扱う上での柔軟性と効率性を飛躍的に向上させました。

## コアとなるコードの変更箇所

このコミットは、Go言語の仕様書である `doc/go_spec.txt` のみを変更しています。実際のコンパイラやランタイムのコード変更は含まれていませんが、Go言語の設計思想と型システムの定義に根本的な影響を与える変更です。

主な変更箇所は以下の通りです。

*   **`doc/go_spec.txt`**:
    *   **「オープン配列」に関する記述の削除**: `Array types` セクションから、長さが指定されていない配列(オープン配列)に関する説明がすべて削除されました。
    *   **「スライス型」セクションの新規追加**: `Slice types` という新しいセクションが追加され、スライスの定義、構造(ポインタ、長さ、容量)、作成方法(`new`)、インデックス操作、スライス操作、代入互換性などが詳細に記述されました。
    *   **配列の定義の変更**: 配列は常に固定長であり、その長さが型の一部であることが明確にされました。`len(a)` が常にコンパイル時定数であることも明記されました。
    *   **マップとチャネルのセマンティクス変更**: `Map types` と `Channel types` のセクションにおいて、これらの型がポインタを介さずに直接値として扱われるように記述が変更されました。`new` 関数がこれらの型に対してポインタではなく、型そのものを返すように修正されました。
    *   **`new` 組み込み関数の説明の更新**: `Allocation` セクションで、`new` 関数がスライス、マップ、チャネルに対しては型そのものを返し、他の型に対してはポインタを返すという新しいセマンティクスが反映されました。
    *   **型等価性および同一性のルールの更新**: `Type equality` と `Identical types` のセクションで、配列とスライスの等価性/同一性に関するルールが、新しい型システムに合わせて修正されました。
    *   **`Values and references` セクションの修正**: ほとんどのデータ型が値セマンティクスを持つが、一部のデータ型(スライス、マップ、チャネル)は参照セマンティクスを持つことが明記されました。

## コアとなるコードの解説

このコミットは、Go言語の仕様書である `doc/go_spec.txt` のテキスト変更のみであり、直接的な「コード」の変更はありません。しかし、そのテキスト変更がGo言語のコアな振る舞いを定義しているため、その変更内容自体が「コアとなるコードの解説」に相当します。

最も重要な変更は、`doc/go_spec.txt` 内で「オープン配列」という概念が完全に削除され、代わりに「スライス型」が導入されたことです。

**変更前(オープン配列の概念)**:
以前の仕様では、`[]T` のような構文が「オープン配列」として扱われ、動的なサイズの配列を表現しようとしていました。しかし、これは固定長配列と混同されやすく、そのセマンティクスが不明瞭でした。特に、`new([]int, 100)` のようにオープン配列のポインタを返すような記述があり、ポインタを介して操作する必要がありました。

**変更後(スライス型の導入)**:
このコミットにより、`[]T` は明確に「スライス型」として定義されました。スライスは、基盤となる配列への「ビュー」を提供し、ポインタ、長さ、容量という3つの要素で構成されます。

```diff
--- a/doc/go_spec.txt
+++ b/doc/go_spec.txt
@@ -1188,133 +1202,36 @@ just array of bytes) by a conversion (§Conversions):
 Array types
 ----
 
-An array is a composite type consisting of a number of elements all of the same
-type, called the element type. The number of elements of an array is called its
-length; it is always positive (including zero).  The elements of an array are
-designated by indices which are integers between 0 and the length - 1.
-
-An array type specifies the array element type and an optional array
-length which must be a compile-time constant expression of a (signed or
-unsigned) int type. If present, the array length and its value is part of
-the array type. The element type must be a complete type (§Types).
-
-If the length is present in the declaration, the array is called
-``fixed array''; if the length is absent, the array is called ``open array''.
+An array is a composite type consisting of a number of elements all of the
+same type, called the element type. The element type must be a complete type
+(§Types). The number of elements of an array is called its length; it is never
+negative. The elements of an array are designated by indices
+which are integers from 0 through the length - 1.
 
-\tArrayType = "[" [ ArrayLength ] "]" ElementType .
+\tArrayType = "[" ArrayLength "]" ElementType .
 \tArrayLength = Expression .
 \tElementType = CompleteType .
 
-The length of an array "a" can be discovered using the built-in function
+The array length and its value are part of the array type. The array length
+must be a constant expression (§Constant expressions) that evaluates to an
+integer value >= 0.
 
-\tlen(a)
-\t
-If "a" is a fixed array, the length is known at compile-time and "len(a)" can
-be evaluated to a compile-time constant. If "a" is an open array, then "len(a)"
-will only be known at run-time.
-
-The amount of space actually allocated to hold the array data may be larger
-then the current array length; this maximum array length is called the array
-capacity. The capacity of an array "a" can be discovered using the built-in
+The number of elements of an array "a" can be discovered using the built-in
 function
 
-\tcap(a)
-\t
-and the following relationship between "len()" and "cap()" holds:
-
-\t0 <= len(a) <= cap(a)
-
-Allocation: An open array may only be used as a function parameter type, or
-as element type of a pointer type. There are no other variables
-(besides parameters), struct or map fields of open array type; they must be
-pointers to open arrays. For instance, an open array may have a fixed array
-element type, but a fixed array must not have an open array element type
-(though it may have a pointer to an open array). Thus, for now, there are
-only ``one-dimensional'' open arrays.
+\tlen(a)
 
-The following are legal array types:
+The length of arrays is known at compile-time, and the result of a call to
+"len(a)" is a compile-time constant.
 
-\t[32] byte
+\t[32]byte
  [2*N] struct { x, y int32 }
-\t[1000]*[] float64
-\t[] int
-\t[][1024] byte
-\t
-Variables of fixed arrays may be declared statically:
-
-\tvar a [32] byte
-\tvar m [1000]*[] float64
-
-Static and dynamic arrays may be allocated dynamically via the built-in function
-"new()" which takes an array type and zero or one array lengths as parameters,
-depending on the number of open arrays in the type:
-
-\tnew([32] byte)                // *[32] byte
-\tnew([]int, 100);              // *[100] int
-\tnew([][1024] byte, 4);        // *[4][1024] byte
-
-Assignment compatibility: Fixed arrays are assignment compatible to variables
-of the same type, or to open arrays with the same element type. Open arrays
-may only be assigned to other open arrays with the same element type.
-
-For the variables:
-
-\tvar fa, fb [32] int
-\tvar fc [64] int
-\tvar pa, pb *[] int
-\tvar pc *[][32] int
-
-the following assignments are legal, and cause the respective array elements
-to be copied:
-
-\tfa = fb;
-\tpa = pb;
-\t*pa = *pb;
-\tfa = *pc[7];
-\t*pa = fa;
-\t*pb = fc;
-\t*pa = *pc[11];
-
-The following assignments are illegal:
-
-\tfa = *pa;      // cannot assign open array to fixed array
-\t*pc[7] = *pa;  // cannot assign open array to fixed array
-\tfa = fc;       // different fixed array types
-\t*pa = *pc;     // different element types of open arrays
-
-
-Array indexing: Given a (pointer to an) array variable "a", an array element
-is specified with an array index operation:
-
-\ta[i]
-\t
-This selects the array element at index "i". "i" must be within array bounds,
-that is "0 <= i < len(a)".
-
-Array slicing: Given a (pointer to an) array variable "a", a sub-array is
-specified with an array slice operation:
-
-\ta[i : j]
-\t
-This selects the sub-array consisting of the elements "a[i]" through "a[j - 1]"
-(exclusive "a[j]"). "i" must be within array bounds, and "j" must satisfy
-"i <= j <= cap(a)". The length of the new slice is "j - i". The capacity of
-the slice is "cap(a) - i"; thus if "i" is 0, the array capacity does not change
-as a result of a slice operation. An array slice is always an open array.
-
-Note that a slice operation does not ``crop'' the underlying array, it only
-provides a new ``view'' to an array. If the capacity of an array is larger
-then its length, slicing can be used to ``grow'' an array:
+\t[1000]*float64
 
-\t// allocate an open array of bytes with length i and capacity 100
-\ti := 10;
-\ta := new([] byte, 100) [0 : i];
-\t// grow the array by n bytes, with i + n <= 100
-\ta = a[0 : i + n];
-\n-\n-TODO: Expand on details of slicing and assignment, especially between pointers
-- to arrays and arrays.
+Assignment compatibility: Arrays can be assigned to slice variables of
+equal element type; arrays cannot be assigned to other array variables
+or passed to functions (by value).
+TODO rethink this restriction. Causes irregularities.

この差分は、Array types セクションから「オープン配列」に関する記述が丸ごと削除され、配列が常に固定長であることが強調されていることを示しています。そして、新たに Slice types セクションが追加され、スライスの詳細なセマンティクスが定義されました。

--- a/doc/go_spec.txt
+++ b/doc/go_spec.txt
@@ -1593,6 +1448,148 @@ Assignment compatibility: A value can be assigned to an interface variable
 if the static type of the value implements the interface or if the value is "nil".
 
 
+Slice types
+----
+
+An (array) slice type denotes the set of all slices (segments) of arrays
+(§Array types) of a given element type, and the value "nil".
+The number of elements of a slice is called its length; it is never negative.
+The elements of a slice are designated by indices which are
+integers from 0 through the length - 1.
+
+\tSliceType = "[" "]" ElementType .
+
+Syntactically and semantically, arrays and slices look and behave very
+similarly, but with one important difference: A slice is a descriptor
+of an array segment; in particular, different variables of a slice type may
+refer to different (and possibly overlapping) segments of the same underlying
+array. Thus, with respect to the underlying array, slices behave like
+references. In contrast, two different variables of array type always
+denote two different arrays.
+
+For slices, the actual array underlying the slice may extend past the current
+slice length; the maximum length a slice may assume is called its capacity.
+The capacity of any slice "a" can be discovered using the built-in function
+
+\tcap(a)
+
+and the following relationship between "len()" and "cap()" holds:
+
+\t0 <= len(a) <= cap(a)
+
+The value of an uninitialized slice is "nil", and its length and capacity
+are 0. A new, initialized slice value for a given elemen type T is
+created using the built-in function "new", which takes a slice type
+and parameters specifying the length and optionally the capacity:
+
+\tnew([]T, length)
+\tnew([]T, length, capacity)
+
+Assignment compatibility: Slices are assignment compatible to variables
+of the same type.
+
+Indexing: Given a (pointer to) a slice variable "a", a slice element is
+specified with an index operation:
+
+\ta[i]
+
+This denotes the slice element at index "i". "i" must be within bounds,
+that is "0 <= i < len(a)".
+
+Slicing: Given a a slice variable "a", a sub-slice is created with a slice
+operation:
+
+\ta[i : j]
+
+This creates the sub-slice consisting of the elements "a[i]" through "a[j - 1]"
+(that is, excluding "a[j]"). "i" must be within array bounds, and "j" must satisfy
+"i <= j <= cap(a)". The length of the new slice is "j - i". The capacity of
+the slice is "cap(a) - i"; thus if "i" is 0, the slice capacity does not change
+as a result of a slice operation. The type of a sub-slice is the same as the
+type of the slice.
+
+TODO what are the proper restrictions on slices?
+TODO describe equality checking against nil

この新しい Slice types セクションは、スライスが配列のセグメントを記述するものであり、基盤となる配列に対して参照のように振る舞うことを明確にしています。また、lencap の概念がスライスに適用され、new 関数によるスライスの作成方法も定義されています。

さらに、new 組み込み関数のセマンティクスも変更されました。

--- a/doc/go_spec.txt
+++ b/doc/go_spec.txt
@@ -3159,9 +3162,10 @@ Allocation
 ----
 
 The built-in function "new()" takes a type "T", optionally followed by a
-type-specific list of expressions. It allocates memory for a variable
-of type "T" and returns a pointer of type "*T" to that variable. The
-memory is initialized as described in the section on initial values
+type-specific list of expressions. It returns a value of type "T" (possibly
+by allocating memory in the heap).
+TODO describe initialization
+The memory is initialized as described in the section on initial values
 (§Program initialization and execution).\n
 \tnew(type [, optional list of expressions])\n
@@ -3169,7 +3173,7 @@ memory is initialized as described in the section on initial values\n For instance\n \n \ttype S struct { a int; b float }\n-\tnew(S)\n+\tnew(*S)\n \n dynamically allocates memory for a variable of type S, initializes it\n (a=0, b=0.0), and returns a value of type *S pointing to that variable.\n@@ -3177,24 +3181,11 @@ dynamically allocates memory for a variable of type S, initializes it\n The only defined parameters affect sizes for allocating arrays,\n buffered channels, and maps.\n \n-\tap := new([]int, 10);            # a pointer to an open array of 10 ints\n-\tc := new(chan int, 10);          # a pointer to a channel with a buffer size of 10\n-\tm := new(map[string] int, 100);  # a pointer to a map with initial space for 100 elements\n-\n-For arrays, a third argument may be provided to specify the array capacity:\n-\n-\tbp := new([]byte, 0, 1024);      # a pointer to an empty open array with capacity 1024\n+\ts := new([]int);\t\t\t\t # slice\n+\tc := new(chan int, 10);          # channel with a buffer size of 10\n+\tm := new(map[string] int, 100);  # map with initial space for 100 elements\n \n-<!--\n-TODO gri thinks that we should not use this notation to specify the capacity\n-for the following reasons: a) It precludes the future use of that argument as the length\n-for multi-dimensional open arrays (which we may need at some point) and b) the\n-effect of "new(T, l, c)" is trivially obtained via "new(T, c)[0 : l]", doesn't\n-require extra explanation, and leaves options open.\n-Finally, if there is a performance concern (the single new() may be faster\n-then the new() with slice, the compiler can trivially rewrite the slice version\n-into a faster internal call that doesn't do slicing).\n--->\n+TODO revisit this section

この差分は、new が常にポインタを返すのではなく、スライス、マップ、チャネルに対しては型そのものを返すように変更されたことを示しています。これにより、これらの型が値セマンティクスを持つというGoの設計思想がより明確に反映されました。

これらの変更は、Go言語のデータ構造のセマンティクスを根本的に再構築し、後のGo言語の成功に不可欠な、直感的で効率的なスライス、マップ、チャネルの振る舞いの基礎を築きました。

関連リンク

参考にした情報源リンク