mirror of https://github.com/golang/go.git
Clarify conversions, include making them constructors for arrays etc.
SVN=118194
This commit is contained in:
parent
9bc7b08abb
commit
f4f588372d
164
doc/go_lang.txt
164
doc/go_lang.txt
|
|
@ -623,54 +623,6 @@ followed by a parenthesized expression list. In effect, they are a
|
||||||
conversion from expression list to compound value.
|
conversion from expression list to compound value.
|
||||||
|
|
||||||
|
|
||||||
Array literals
|
|
||||||
----
|
|
||||||
|
|
||||||
Array literals represent array values. All the contained expressions must
|
|
||||||
be of the same type, which is the element type of the resulting array.
|
|
||||||
|
|
||||||
ArrayLit = ArrayType "(" [ ExpressionList ] ")" .
|
|
||||||
|
|
||||||
[]int()
|
|
||||||
[]int(1, 2, 3)
|
|
||||||
[]string("x", "y")
|
|
||||||
|
|
||||||
Unresolved issues: Are elements converted? What about length?
|
|
||||||
|
|
||||||
|
|
||||||
Map Literals
|
|
||||||
----
|
|
||||||
|
|
||||||
Map literals represent map values. They comprise a list of (key, value)
|
|
||||||
pairs written as successive values.
|
|
||||||
All keys must have the same type; all values must have the same type.
|
|
||||||
|
|
||||||
|
|
||||||
MapLit = MapType "(" KeyValueList ")" .
|
|
||||||
KeyValueList = [ KeyValue { "," KeyValue } ].
|
|
||||||
KeyValue = Expression "," Expression .
|
|
||||||
|
|
||||||
[string]map int("one",1, "two",2)
|
|
||||||
[int]map bool(2,true, 3,true, 5,true, 7,true)
|
|
||||||
|
|
||||||
Unresolved issues: Are elements converted?
|
|
||||||
Colon for a separator or comma?
|
|
||||||
|
|
||||||
|
|
||||||
Struct literals
|
|
||||||
----
|
|
||||||
|
|
||||||
Struct literals represent struct constants. They comprise a list of
|
|
||||||
expressions that represent the individual fields of a struct. The
|
|
||||||
individual expressions must match those of the specified struct type.
|
|
||||||
|
|
||||||
StructLit = StructType "(" [ ExpressionList ] ")" .
|
|
||||||
|
|
||||||
Point(2, 3)
|
|
||||||
ColoredPoint(4, 4, "green")
|
|
||||||
struct { a, b int } (7, 8)
|
|
||||||
|
|
||||||
|
|
||||||
Pointer types
|
Pointer types
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
@ -699,8 +651,6 @@ can be constructed such as:
|
||||||
By the end of the package source, all forward-declared types must be
|
By the end of the package source, all forward-declared types must be
|
||||||
fully declared if they are used.
|
fully declared if they are used.
|
||||||
|
|
||||||
There are no pointer literals.
|
|
||||||
|
|
||||||
|
|
||||||
Channel types
|
Channel types
|
||||||
----
|
----
|
||||||
|
|
@ -727,9 +677,6 @@ particular to dereference a channel pointer.
|
||||||
var ch *chan int;
|
var ch *chan int;
|
||||||
ch = new(chan int); // new returns type *chan int
|
ch = new(chan int); // new returns type *chan int
|
||||||
|
|
||||||
There are no channel literals.
|
|
||||||
|
|
||||||
|
|
||||||
Function types
|
Function types
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
@ -879,8 +826,6 @@ compatible interface type. It is legal to assign an interface
|
||||||
variable to any struct pointer variable but if the struct type is
|
variable to any struct pointer variable but if the struct type is
|
||||||
incompatible the result will be nil.
|
incompatible the result will be nil.
|
||||||
|
|
||||||
There are no interface literals.
|
|
||||||
|
|
||||||
|
|
||||||
The polymorphic "any" type
|
The polymorphic "any" type
|
||||||
----
|
----
|
||||||
|
|
@ -949,9 +894,7 @@ vice versa. Note that the declaration order of the methods is not relevant.
|
||||||
Literals
|
Literals
|
||||||
----
|
----
|
||||||
|
|
||||||
Literal = BasicLit | CompoundLit .
|
Literal = char_lit | string_lit | int_lit | float_lit | FunctionLit | "nil" .
|
||||||
BasicLit = char_lit | string_lit | int_lit | float_lit | "nil" .
|
|
||||||
CompoundLit = ArrayLit | MapLit | StructLit | FunctionLit .
|
|
||||||
|
|
||||||
|
|
||||||
Declarations
|
Declarations
|
||||||
|
|
@ -1159,8 +1102,9 @@ Expression syntax is based on that of C but with fewer precedence levels.
|
||||||
Expression "." "(" Type ")" .
|
Expression "." "(" Type ")" .
|
||||||
|
|
||||||
Call = Expression "(" [ ExpressionList ] ")" .
|
Call = Expression "(" [ ExpressionList ] ")" .
|
||||||
Conversion = TypeName "(" Expression ")" |
|
Conversion = "convert" "(" Type [ "," ExpressionList ] ")" |
|
||||||
"convert" "(" Type "," Expression ")" .
|
ConversionType "(" [ ExpressionList ] ")" .
|
||||||
|
ConversionType = TypeName | ArrayType | MapType | StructType | InterfaceType .
|
||||||
Allocation = "new" "(" Type [ "," Expression ] ")" .
|
Allocation = "new" "(" Type [ "," Expression ] ")" .
|
||||||
|
|
||||||
binary_op = log_op | rel_op | add_op | mul_op .
|
binary_op = log_op | rel_op | add_op | mul_op .
|
||||||
|
|
@ -1245,7 +1189,7 @@ The keyword
|
||||||
represents the ``zero'' value for a pointer type or interface type.
|
represents the ``zero'' value for a pointer type or interface type.
|
||||||
|
|
||||||
The only operations allowed for nil are to assign it to a pointer or
|
The only operations allowed for nil are to assign it to a pointer or
|
||||||
interface value and to compare it for equality or inquality with a
|
interface variable and to compare it for equality or inequality with a
|
||||||
pointer or interface value.
|
pointer or interface value.
|
||||||
|
|
||||||
var p *int;
|
var p *int;
|
||||||
|
|
@ -1261,6 +1205,8 @@ TODO: how does this definition jibe with using nil to specify
|
||||||
conversion failure if the result is not of pointer type, such
|
conversion failure if the result is not of pointer type, such
|
||||||
as an any variable holding an int?
|
as an any variable holding an int?
|
||||||
|
|
||||||
|
TODO: if interfaces were explicitly pointers, this gets simpler.
|
||||||
|
|
||||||
|
|
||||||
Allocation
|
Allocation
|
||||||
----
|
----
|
||||||
|
|
@ -1294,40 +1240,82 @@ TODO: argument order for dimensions in multidimensional arrays
|
||||||
Conversions
|
Conversions
|
||||||
----
|
----
|
||||||
|
|
||||||
There are three ways to convert a value from one type to another.
|
Conversions create new values of a specified type derived from the
|
||||||
|
elements of a list of expressions of a different type.
|
||||||
|
|
||||||
The most general is a call to the intrinsic special function "convert"
|
The most general conversion takes the form of a call to "convert",
|
||||||
with arguments the type name and the value to be converted.
|
with the result type and a list of expressions as arguments:
|
||||||
|
|
||||||
var i int = convert(int, PI * 1000.0);
|
convert(int, PI * 1000.0);
|
||||||
chars_as_ints := convert([]int, "now is the time");
|
convert([]int, 1, 2, 3, 4);
|
||||||
|
|
||||||
If the destination type is a known type name, the conversion can be
|
If the result type is a basic type, pointer type, or
|
||||||
rewritten to look syntactically like a call to a function with that
|
interface type, there must be exactly one expression and there is a
|
||||||
name.
|
specific set of permitted conversions, detailed later in the section.
|
||||||
|
These conversions are called ``simple conversions''.
|
||||||
|
TODO: if interfaces were explicitly pointers, this gets simpler.
|
||||||
|
|
||||||
i := int(PI * 1000.0);
|
convert(int, 3.14159);
|
||||||
s := AStructType(an_interface_variable);
|
convert(uint32, ~0);
|
||||||
|
convert(interface{}, new(S))
|
||||||
|
convert(*AStructType, interface_value)
|
||||||
|
|
||||||
A conversion can be written as a parenthesized type after a period.
|
For other result types - arrays, maps, structs - the expressions
|
||||||
Although intended for ease of conversion within a method call chain,
|
form a list of values to be assigned to successive elements of the
|
||||||
this form works in any expression context.
|
resulting value. If the type is an array or map, the list may even be
|
||||||
|
empty. Unlike in a simple conversion, the types of the expressions
|
||||||
|
must be equivalent to the types of the elements of the result type;
|
||||||
|
the individual values are not converted. For instance, if result
|
||||||
|
type is []int, the expressions must be all of type int, not float or
|
||||||
|
uint. (For maps, the successive elements must be key-value pairs).
|
||||||
|
For arrays and struct types, if fewer elements are provided than
|
||||||
|
specified by the result type, the missing elements are
|
||||||
|
initialized to the respective ``zero'' value for that element type.
|
||||||
|
|
||||||
|
These conversions are called ``compound conversions''.
|
||||||
|
|
||||||
|
convert([]int) // empty array of ints
|
||||||
|
convert([]int, 1, 2, 3)
|
||||||
|
convert([5]int, 1, 2); // == convert([5]int, 1, 2, 0, 0, 0)
|
||||||
|
convert(map[string]int, "1", 1, "2", 2)
|
||||||
|
convert(struct{ x int; y float }, 3, sqrt(2.0))
|
||||||
|
|
||||||
|
There is syntactic help to make conversion expressions simpler to write.
|
||||||
|
|
||||||
|
If the result type is of ConversionType (a type name, array type,
|
||||||
|
map type, structure type, or interface type, essentially anything
|
||||||
|
except a pointer), the conversion can be rewritten to look
|
||||||
|
syntactically like a call to a function whose name is the type:
|
||||||
|
|
||||||
|
int(PI * 1000.0);
|
||||||
|
AStructType(an_interface_variable);
|
||||||
|
struct{ x int, y float }(3, sqrt(2.0))
|
||||||
|
[]int(1, 2, 3, 4);
|
||||||
|
map[string]int("1", 1, "2", 2);
|
||||||
|
|
||||||
|
This notation is convenient for declaring and initializing
|
||||||
|
variables of composite type:
|
||||||
|
|
||||||
|
primes := []int(2, 3, 5, 7, 9, 11, 13);
|
||||||
|
|
||||||
|
Simple conversions can also be written as a parenthesized type after
|
||||||
|
an expression and a period. Although intended for ease of conversion
|
||||||
|
within a method call chain, this form works in any expression context.
|
||||||
|
TODO: should it?
|
||||||
|
|
||||||
var s *AStructType = vec.index(2).(*AStructType);
|
var s *AStructType = vec.index(2).(*AStructType);
|
||||||
fld := vec.index(2).(*AStructType).field;
|
fld := vec.index(2).(*AStructType).field;
|
||||||
f := 1000.(float);
|
a := foo[i].(string);
|
||||||
|
|
||||||
TODO: are there parameters to any conversions? go.y has oexpr_list as the
|
As said, for compound conversions the element types must be equivalent.
|
||||||
contents of a TypeName() conversion; i expected expr instead and that's what
|
For simple conversions, the types can differ but only some combinations
|
||||||
the others have.
|
are permitted:
|
||||||
|
|
||||||
Only some conversions are permitted.
|
|
||||||
|
|
||||||
1) Between integer types. If the value is a signed quantity, it is
|
1) Between integer types. If the value is a signed quantity, it is
|
||||||
sign extended to implicit infinite precision; otherwise it is zero
|
sign extended to implicit infinite precision; otherwise it is zero
|
||||||
extended. It is then truncated to fit in the destination type size.
|
extended. It is then truncated to fit in the result type size.
|
||||||
For example, uint32(int8(0xFF)) is 0xFFFFFFFF. The conversion always
|
For example, uint32(int8(0xFF)) is 0xFFFFFFFF. The conversion always
|
||||||
yields a valid value; for instance, there is no signal for overflow.
|
yields a valid value; there is no signal for overflow.
|
||||||
|
|
||||||
2) Between integer and floating point types, or between floating point
|
2) Between integer and floating point types, or between floating point
|
||||||
types. To avoid overdefining the properties of the conversion, for
|
types. To avoid overdefining the properties of the conversion, for
|
||||||
|
|
@ -1344,6 +1332,18 @@ should incompatible conversions fail immediately?
|
||||||
conversions yield nil values. TODO: is nil right here? Or should
|
conversions yield nil values. TODO: is nil right here? Or should
|
||||||
incompatible conversions fail immediately?
|
incompatible conversions fail immediately?
|
||||||
|
|
||||||
|
5) Strings permit two special conversions.
|
||||||
|
|
||||||
|
5a) Converting an integer value yields a string containing the UTF-8
|
||||||
|
representation of the integer.
|
||||||
|
|
||||||
|
string(0x65e5) // "\u65e5"
|
||||||
|
|
||||||
|
5b) Converting an array of uint8s yields a string whose successive
|
||||||
|
bytes are those of the array. (Recall byte is a synonym for uint8.)
|
||||||
|
|
||||||
|
string([]byte('h', 'e', 'l', 'l', 'o')) // "hello"
|
||||||
|
|
||||||
Note that there is no linguistic mechanism to convert between pointers
|
Note that there is no linguistic mechanism to convert between pointers
|
||||||
and integers. A library may be provided under restricted circumstances
|
and integers. A library may be provided under restricted circumstances
|
||||||
to acccess this conversion in low-level code but it will not be available
|
to acccess this conversion in low-level code but it will not be available
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue