Robert Griesemer, Rob Pike, Ken Thompson
-(January 5, 2009)
+(January 6, 2009)
----
Length and capacity
Conversions
Allocation
+ Making slices, maps, and channels
Packages
The predeclared functions (note: this list is likely to change):
- cap(), convert(), len(), new(), panic(), panicln(), print(), println(), typeof(), ...
+ cap(), convert(), len(), make(), new(), panic(), panicln(), print(), println(), typeof(), ...
Exported declarations
Slice types
----
-An (array) slice type denotes the set of all slices (segments) of arrays
+A 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
0 <= 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
+are 0. A new, initialized slice value for a given element type T is
+made using the built-in function "make", which takes a slice type
and parameters specifying the length and optionally the capacity:
- new([]T, length)
- new([]T, length, capacity)
+ make([]T, length)
+ make([]T, length, capacity)
+
+The "make()" call allocates a new underlying array to which the returned
+slice value refers. More precisely, calling "make"
+
+ make([]T, length, capacity)
+
+is effectively the same as allocating an array and slicing it
+
+ new([capacity]T)[0 : length]
Assignment compatibility: Slices are assignment compatible to variables
of the same type.
"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.
+type of the slice. Unlike the capacity, the length of a sub-slice
+may be larger than the length of the original slice.
TODO what are the proper restrictions on slices?
TODO describe equality checking against nil
len(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:
+The value of an uninitialized map is "nil". A new, empty map
+value for given key and value types K and V is made using the built-in
+function "make" which takes the map type and an (optional) capacity as arguments:
- my_map := new(map[K] V, 100);
+ my_map := make(map[K] V, 100);
The map capacity is an allocation hint for more efficient incremental growth
of the map.
<-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:
+value for a given element type T is made using the built-in function "make",
+which takes the channel type and an optional capacity as arguments:
- my_chan = new(chan int, 100);
+ my_chan = make(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
Slices
----
-Strings and arrays can be ``sliced'' to construct substrings or subarrays.
-The index expressions in the slice select which elements appear in the
-result. The result has indexes starting at 0 and length equal to the difference
-in the index values in the slice. After
+Strings, arrays, and slices can be ``sliced'' to construct substrings or descriptors
+of subarrays. The index expressions in the slice select which elements appear
+in the result. The result has indexes starting at 0 and length equal to the
+difference in the index values in the slice. After slicing the array "a"
- a := []int(1,2,3,4)
- slice := a[1:3]
+ a := [4]int{1, 2, 3, 4};
+ s := a[1:3];
-The array ``slice'' has length two and elements
+the slice "s" has type "[]int", length 2, and elements
- slice[0] == 2
- slice[1] == 3
+ s[0] == 2
+ s[1] == 3
The index values in the slice must be in bounds for the original
array (or string) and the slice length must be non-negative.
-Slices are new arrays (or strings) storing copies of the elements, so
-changes to the elements of the slice do not affect the original.
-In the example, a subsequent assignment to element 0,
-
- slice[0] = 5
-
-would have no effect on ``a''.
+If the sliced operand is a string, the result of the slice operation is another
+string (§String types). If the sliced operand is an array or slice, the result
+of the slice operation is a slice (§Slice types).
Type guards
Here the term "channel" means "variable of type chan".
-A channel is created by allocating it:
+The built-in function "make" makes a new channel value:
- ch := new(chan int)
+ ch := make(chan int)
-An optional argument to new() specifies a buffer size for an
+An optional argument to "make()" specifies a buffer size for an
asynchronous channel; if absent or zero, the channel is synchronous:
- sync_chan := new(chan int)
- buffered_chan := new(chan int, 10)
+ sync_chan := make(chan int)
+ buffered_chan := make(chan int, 10)
The send operation uses the binary operator "<-", which operates on
a channel and a value (expression):
cap
convert
len
+ make
new
panic
+ panicln
print
+ println
typeof
Length and capacity
----
-The predeclared function "len()" takes a value of type string,
-array or map type, or of pointer to array or map type, and
-returns the length of the string in bytes, or the number of array
-of map elements, respectively.
+ Call Argument type Result
-The predeclared function "cap()" takes a value of array or pointer
-to array type and returns the number of elements for which there
-is space allocated in the array. For an array "a", at any time the
-following relationship holds:
+ len(s) string, *string string length (in bytes)
+ [n]T, *[n]T array length (== n)
+ []T, *[]T slice length
+ map[K]T, *map[K]T map length
+ chan T number of elements in channel buffer
- 0 <= len(a) <= cap(a)
+ cap(s) []T, *[]T capacity of s
+ map[K]T, *map[K]T capacity of s
+ chan T channel buffer capacity
+
+TODO: confirm len() and cap() for channels
+
+The type of the result is always "int" and the implementation guarantees that
+the result always fits into an "int".
-TODO(gri) Change this and the following sections to use a table indexed
-by functions and parameter types instead of lots of prose.
+The capacity of a slice or map is the number of elements for which there is
+space allocated in the underlying array (for a slice) or map. For a slice "s",
+at any time the following relationship holds:
+
+ 0 <= len(s) <= cap(s)
Conversions
Allocation
----
-The built-in function "new()" takes a type "T", optionally followed by a
-type-specific list of expressions. It returns a value of type "T" (possibly
-by allocating memory in the heap).
-TODO describe initialization
+The built-in function "new" takes a type "T" and returns a value of type "*T".
The memory is initialized as described in the section on initial values
(§Program initialization and execution).
- new(type [, optional list of expressions])
+ new(T)
For instance
type S struct { a int; b float }
- new(*S)
+ new(S)
dynamically allocates memory for a variable of type S, initializes it
(a=0, b=0.0), and returns a value of type *S pointing to that variable.
-The only defined parameters affect sizes for allocating arrays,
-buffered channels, and maps.
- s := new([]int); # slice
- c := new(chan int, 10); # channel with a buffer size of 10
- m := new(map[string] int, 100); # map with initial space for 100 elements
+TODO Once this has become clearer, connect new() and make() (new() may be
+explained by make() and vice versa).
+
+
+Making slices, maps, and channels
+----
+
+The built-in function "make" takes a type "T", optionally followed by a
+type-specific list of expressions. It returns a value of type "T". "T"
+must be a slice, map, or channel type.
+The memory is initialized as described in the section on initial values
+(§Program initialization and execution).
+
+ make(T [, optional list of expressions])
+
+For instance
+
+ make(map[string] int)
+
+creates a new map value and initializes it to an empty map.
+
+The only defined parameters affect sizes for allocating slices, maps, and
+buffered channels:
+
+ s := make([]int, 10, 100); # slice with len(s) == 10, cap(s) == 100
+ c := make(chan int, 10); # channel with a buffer size of 10
+ m := make(map[string] int, 100); # map with initial space for 100 elements
-TODO revisit this section
+TODO Once this has become clearer, connect new() and make() (new() may be
+explained by make() and vice versa).
----
// The prime sieve: Daisy-chain Filter processes together.
func Sieve() {
- ch := new(chan int); // Create a new channel.
+ ch := make(chan int); // Create a new channel.
go Generate(ch); // Start Generate() as a subprocess.
for {
prime := <-ch;
print(prime, "\n");
- ch1 := new(chan int);
+ ch1 := make(chan int);
go Filter(ch, ch1, prime);
ch = ch1
}