1
0
mirror of https://github.com/golang/go synced 2024-11-24 20:40:23 -07:00

key:value notation for composites

R=rsc
DELTA=106  (69 added, 9 deleted, 28 changed)
OCL=29203
CL=29254
This commit is contained in:
Robert Griesemer 2009-05-22 10:25:06 -07:00
parent 7d4765e2d3
commit 838cf124f0

View File

@ -1805,30 +1805,62 @@ Is it needed?
Composite literals construct values for structs, arrays, slices, and maps Composite literals construct values for structs, arrays, slices, and maps
and create a new value each time they are evaluated. and create a new value each time they are evaluated.
They consist of the type of the value They consist of the type of the value
followed by a brace-bound list of expressions, followed by a brace-bound list of composite elements. An element may be
or a list of key-value pairs for map literals. a single expression or a key-value pair.
</p> </p>
<pre class="grammar"> <pre class="grammar">
CompositeLit = LiteralType "{" [ ( ExpressionList | KeyValueList ) [ "," ] ] "}" . CompositeLit = LiteralType "{" [ ElementList ] "}" .
LiteralType = StructType | ArrayType | "[" "..." "]" ElementType | LiteralType = StructType | ArrayType | "[" "..." "]" ElementType |
SliceType | MapType | TypeName . SliceType | MapType | TypeName .
KeyValueList = KeyValueExpr { "," KeyValueExpr } . ElementList = Element { "," Element } [ "," ] .
KeyValueExpr = Expression ":" Expression . Element = [ Key ":" ] Value .
Key = Expression .
Value = Expression .
</pre> </pre>
<p> <p>
The LiteralType must be a struct, array, slice, or map type. The LiteralType must be a struct, array, slice, or map type
(The grammar enforces this constraint except when the type is given (the grammar enforces this constraint except when the type is given
as a TypeName.) as a TypeName).
The types of the expressions must be assignment compatible to The types of the expressions must be assignment compatible to
the respective field, element, and key types of the LiteralType; the respective field, element, and key types of the LiteralType;
there is no additional conversion. there is no additional conversion.
The key is interpreted as a field name for struct literals,
an index for array and slice literals, and a key for map literals.
For map literals, all elements must have a key. It is an error
to specify multiple elements with the same field name or
constant key value.
</p> </p>
<p>
For struct literals the following rules apply:
<ul>
<li>A literal which does not contain any keys must
list an element for each struct field in the
order in which the fields are declared.
</li>
<li>If any element has a key, every element must have a key.
</li>
<li>A literal which contains keys does not need to
have an element for each struct field. Omitted fields
get the zero value for that field.
</li>
<li>A literal may omit the element list; such a literal evaluates
to the zero value for its type.
</li>
<li>It is an error to specify an element for a non-exported
field of a struct belonging to a different package.
</li>
</ul>
</p>
<p>
Given the declarations
</p>
<pre> <pre>
type Rat struct { num, den int } type Point struct { x, y, z float }
type Num struct { r Rat; f float; s string } type Line struct { p, q Point }
</pre> </pre>
<p> <p>
@ -1836,36 +1868,51 @@ one may write
</p> </p>
<pre> <pre>
pi := Num{Rat{22, 7}, 3.14159, "pi"} origin := Point{}; // zero value for Point
line := Line{origin, Point{y: -4, z: 12.3}}; // zero value for line.q.x
</pre> </pre>
<p>For array and slice literals the following rules apply:
<ul>
<li>Each element has an associated integer index marking
its position in the array.
</li>
<li>An element with a key uses the key as its index; the
key must be a constant integer expression.
</li>
<li>An element without a key uses the previous element's index plus one.
If the first element has no key, its index is zero.
</li>
</ul>
</p>
<p> <p>
Taking the address of a composite literal (§Address operators) Taking the address of a composite literal (§Address operators)
generates a unique pointer to an instance of the literal's value. generates a unique pointer to an instance of the literal's value.
</p> </p>
<pre> <pre>
var pi_ptr *Rat = &amp;Rat{22, 7} var pointer *Point = &amp;Point{y: 1000};
</pre> </pre>
<p> <p>
The length of an array literal is the length specified in the LiteralType. The length of an array literal is the length specified in the LiteralType.
If fewer elements than the length are provided in the literal, the missing If fewer elements than the length are provided in the literal, the missing
elements are set to the zero value for the array element type. elements are set to the zero value for the array element type.
It is an error to provide more elements than specified in the type. The It is an error to provide elements with index values outside the index range
notation <code>...</code> specifies an array length equal of the array. The notation <code>...</code> specifies an array length equal
to the number of elements in the literal. to the maximum element index plus one.
</p> </p>
<pre> <pre>
buffer := [10]string{}; // len(buffer) == 10 buffer := [10]string{}; // len(buffer) == 10
primes := [6]int{2, 3, 5, 7, 9, 11}; // len(primes) == 6 intSet := [6]int{1, 2, 3, 5}; // len(intSet) == 6
days := [...]string{"Sat", "Sun"}; // len(days) == 2 days := [...]string{"Sat", "Sun"}; // len(days) == 2
</pre> </pre>
<p> <p>
A slice literal describes the entire underlying array literal. A slice literal describes the entire underlying array literal.
Thus, the length and capacity of a slice literal is the number of elements Thus, the length and capacity of a slice literal is the maximum
(of the array) provided in the literal. A slice literal has the form element index plus one. A slice literal has the form
</p> </p>
<pre> <pre>
@ -1880,15 +1927,6 @@ and is a shortcut for a slice operation applied to an array literal:
[n]T{x1, x2, ... xn}[0 : n] [n]T{x1, x2, ... xn}[0 : n]
</pre> </pre>
<p>
In map literals only, the list contains
key-value pairs separated by a colon:
</p>
<pre>
m := map[string]int{"good": 0, "bad": 1, "indifferent": 7};
</pre>
<p> <p>
A parsing ambiguity arises when a composite literal using the A parsing ambiguity arises when a composite literal using the
TypeName form of the LiteralType appears in the condition of an TypeName form of the LiteralType appears in the condition of an
@ -1904,6 +1942,28 @@ if x == (T{a,b,c}[i]) { ... }
if (x == T{a,b,c}[i]) { ... } if (x == T{a,b,c}[i]) { ... }
</pre> </pre>
<p>
Examples of valid array, slice, and map literals:
</p>
<pre>
// list of prime numbers
primes := []int{2, 3, 5, 7, 9, 11, 13, 17, 19, 991};
// vowels[ch] is true if ch is a vowel
vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true};
// the array [10]float{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1};
filter := [10]float{-1, 4: -0.1, -0.1, 9: -1};
// frequencies in Hz for equal-tempered scale (A4 = 440Hz)
noteFrequency := map[string]float{
"C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
"G0": 24.50, "A0": 27.50, "B0": 30.87,
}
</pre>
<h3>Function literals</h3> <h3>Function literals</h3>
<p> <p>