Commit 96750f13 authored by Rob Pike's avatar Rob Pike

most of the rest.

only the package section is untouched.

R=gri
DELTA=542  (186 added, 70 deleted, 286 changed)
OCL=25485
CL=25532
parent fadf159a
...@@ -2278,17 +2278,18 @@ returning a value and a boolean indicating success. (§Assignments) ...@@ -2278,17 +2278,18 @@ returning a value and a boolean indicating success. (§Assignments)
<h3>Calls</h3> <h3>Calls</h3>
<p> <p>
Given a function or a function variable <code>f</code> of function type Given an expression <code>f</code> of function type
<code>F</code>, the expression <code>F</code>,
</p> </p>
<pre> <pre>
f(a, b, c) f(a1, a2, ... an)
</pre> </pre>
<p> <p>
calls the function with arguments <code>a, b, c</code>. calls <code>f</code> with arguments <code>a1, a2, ... an</code>.
The arguments must be assignment compatible with the parameters of The arguments must be single-valued expressions
assignment compatible with the parameters of
<code>F</code> and are evaluated before the function is called. <code>F</code> and are evaluated before the function is called.
The type of the expression is the result type The type of the expression is the result type
of <code>F</code>. of <code>F</code>.
...@@ -2859,76 +2860,98 @@ but not <code>uint64</code> or <code>string</code>. ...@@ -2859,76 +2860,98 @@ but not <code>uint64</code> or <code>string</code>.
<h2>Statements</h2> <h2>Statements</h2>
<p>
Statements control execution. Statements control execution.
</p>
<pre class="grammar"> <pre class="grammar">
Statement = Statement = { Label ":" } UnlabeledStatement .
Declaration | LabelDecl | EmptyStat | Label = identifier .
UnlabeledStatement =
Declaration | EmptyStat |
SimpleStat | GoStat | ReturnStat | BreakStat | ContinueStat | GotoStat | SimpleStat | GoStat | ReturnStat | BreakStat | ContinueStat | GotoStat |
FallthroughStat | Block | IfStat | SwitchStat | SelectStat | ForStat | FallthroughStat | Block | IfStat | SwitchStat | SelectStat | ForStat |
DeferStat . DeferStat .
SimpleStat = SimpleStat =
ExpressionStat | IncDecStat | Assignment | SimpleVarDecl . ExpressionStat | IncDecStat | Assignment | SimpleVarDecl .
</pre>
Statements in a statement list are separated by semicolons, which can be StatementList = Statement { Separator Statement } .
omitted in some cases as expressed by the OptSemicolon production. Separator = [ ";" ]
<pre class="grammar">
StatementList = Statement { OptSemicolon Statement } .
</pre> </pre>
<p> <p>
A semicolon may be omitted immediately following: Elements of a list of statements are separated by semicolons,
which may be omitted only if the previous statement:
</p> </p>
<ul> <ul>
<li>a closing parenthesis ")" ending a list of declarations (§Declarations and Scope) <li>ends with the closing parenthesis ")" of a list of declarations
<li>a closing brace "}" ending a type declaration (§Type declarations) (§Declarations and Scope); or</li>
<li>a closing brace "}" ending a block (including switch and select statements) <li>ends with the closing brace "}" of a type declaration
<li>a label declaration (§Label declarations) (§Type declarations); or </li>
<li>ends with the closing brace "}" of a block
(including "switch" and "select" statements).
</ul> </ul>
In all other cases a semicolon is required to separate two statements. Since there <p>
is an empty statement, a statement list can always be ``terminated'' with a semicolon. A labeled statement may be the target of a <code>goto</code>,
<code>break</code> or <code>continue</code> statement.
</p>
<pre>
Error: log.Fatal("error encountered")
</pre>
<h3>Empty statements</h3> <h3>Empty statements</h3>
<p>
The empty statement does nothing. The empty statement does nothing.
</p>
<pre class="grammar"> <pre class="grammar">
EmptyStat = . EmptyStat = .
</pre> </pre>
<p>
A statement list can always in effect be terminated with a semicolon by
adding an empty statement.
</p>
<h3>Expression statements</h3> <h3>Expression statements</h3>
<p>
Function calls, method calls, and channel operations
can appear in statement context.
</p>
<pre class="grammar"> <pre class="grammar">
ExpressionStat = Expression . ExpressionStat = Expression .
</pre> </pre>
<pre> <pre>
f(x+y) f(x+y)
<-ch
</pre> </pre>
<font color=red>
TODO: specify restrictions. 6g only appears to allow calls here.
</font>
<h3>IncDec statements</h3> <h3>IncDec statements</h3>
<p>
The "++" and "--" statements increment or decrement their operands The "++" and "--" statements increment or decrement their operands
by the (ideal) constant value 1. by the ideal numeric value 1. As with an assignment, the operand
must be a variable, pointer indirection, field selector or index expression.
</p>
<pre class="grammar"> <pre class="grammar">
IncDecStat = Expression ( "++" | "--" ) . IncDecStat = Expression ( "++" | "--" ) .
</pre> </pre>
<p>
The following assignment statements (§Assignments) are semantically The following assignment statements (§Assignments) are semantically
equivalent: equivalent:
</p>
<pre class="grammar"> <pre class="grammar">
IncDec statement Assignment IncDec statement Assignment
...@@ -2936,12 +2959,6 @@ x++ x += 1 ...@@ -2936,12 +2959,6 @@ x++ x += 1
x-- x -= 1 x-- x -= 1
</pre> </pre>
Both operators apply to integer and floating point types only.
<p>
Note that increment and decrement are statements, not expressions.
For instance, "x++" cannot be used as an operand in an expression.
<h3>Assignments</h3> <h3>Assignments</h3>
<pre class="grammar"> <pre class="grammar">
...@@ -2950,8 +2967,10 @@ Assignment = ExpressionList assign_op ExpressionList . ...@@ -2950,8 +2967,10 @@ Assignment = ExpressionList assign_op ExpressionList .
assign_op = [ add_op | mul_op ] "=" . assign_op = [ add_op | mul_op ] "=" .
</pre> </pre>
The left-hand side must be an l-value such as a variable, pointer indirection, <p>
or an array index. Each left-hand side operand must be a variable, pointer indirection,
field selector, or index expression.
</p>
<pre> <pre>
x = 1 x = 1
...@@ -2960,60 +2979,63 @@ a[i] = 23 ...@@ -2960,60 +2979,63 @@ a[i] = 23
k = <-ch k = <-ch
</pre> </pre>
As in C, arithmetic binary operators can be combined with assignments: <p>
An <i>assignment operation</i> <code>x</code> <i>op</i><code>=</code>
<pre> <code>y</code> where <i>op</i> is a binary arithmetic operation is equivalent
j <<= 2 to <code>x</code> <code>=</code> <code>x</code> <i>op</i>
</pre> <code>y</code> but evalutates <code>x</code>
only once. The <i>op</i><code>=</code> construct is a single token.
A tuple assignment assigns the individual elements of a multi-valued operation, </p>
such as function evaluation or some channel and map operations, into individual
variables. For instance, a tuple assignment such as
<pre>
v1, v2, v3 = e1, e2, e3
</pre>
assigns the expressions e1, e2, e3 to temporaries and then assigns the temporaries
to the variables v1, v2, v3. Thus
<pre> <pre>
a, b = b, a a[i] <<= 2
</pre> </pre>
exchanges the values of a and b. The tuple assignment <p>
A tuple assignment assigns the individual elements of a multi-valued
operation to a list of variables. There are two forms. In the
first, the right hand operand is a single multi-valued expression
such as a function evaluation or channel or map operation (§Channel
operations, §Map operations). The number of operands on the left
hand side must match the number of values. For instance, If
<code>f</code> is a function returning two values,
</p>
<pre> <pre>
x, y = f() x, y = f()
</pre> </pre>
calls the function f, which must return two values, and assigns them to x and y. <p>
As a special case, retrieving a value from a map, when written as a two-element assigns the first value to <code>x</code> and the second to <code>y</code>.
tuple assignment, assign a value and a boolean. If the value is present in the map, </p>
the value is assigned and the second, boolean variable is set to true. Otherwise,
the variable is unchanged, and the boolean value is set to false.
<pre>
value, present = map_var[key]
</pre>
To delete a value from a map, use a tuple assignment with the map on the left <p>
and a false boolean expression as the second expression on the right, such In the second form, the number of operands on the left must equal the number
as: of expressions on the right, each of which must be single-valued. The
expressions are assigned to temporaries and then the temporaries
are assigned to the variables.
</p>
<pre> <pre>
map_var[key] = value, false a, b = b, a // exchange a and b
</pre> </pre>
In assignments, the type of the expression must match the type of the left-hand side. <p>
In assignments, the type of each value must be assignment compatible
(§Assignment compatibility) with the type of the
operand to which it is assigned.
</p>
<h3>If statements</h3> <h3>If statements</h3>
If statements specify the conditional execution of two branches; the "if" <p>
and the "else" branch. If Expression evaluates to true, "If" statements specify the conditional execution of two branches
the "if" branch is executed. Otherwise the "else" branch is executed if present. according to the value of a boolean expression. If the expression
If Condition is omitted, it is equivalent to true. evaluates to true, the "if" branch is executed, otherwise, if
present, the "else" branch is executed. A missing condition
is equivalent to <code>true</code>.
</p>
<pre class="grammar"> <pre class="grammar">
IfStat = "if" [ [ SimpleStat ] ";" ] [ Expression ] Block [ "else" Statement ] . IfStat = "if" [ [ SimpleStat ] ";" ] [ Expression ] Block [ "else" Statement ] .
...@@ -3025,9 +3047,12 @@ if x > 0 { ...@@ -3025,9 +3047,12 @@ if x > 0 {
} }
</pre> </pre>
An "if" statement may include the declaration of a single temporary variable. <code>
The scope of the declared variable extends to the end of the if statement, and An "if" statement may include a short variable declaration before the expression
the variable is initialized once before the statement is entered. (§Short variable declarations).
The scope of the declared variables extends to the end of the "if" statement
and the variables are initialized once before the statement is entered.
</code>
<pre> <pre>
if x := f(); x < y { if x := f(); x < y {
...@@ -3063,7 +3088,13 @@ without the surrounding Block: ...@@ -3063,7 +3088,13 @@ without the surrounding Block:
<h3>Switch statements</h3> <h3>Switch statements</h3>
Switches provide multi-way execution. <p>
"Switch" statements provide multi-way execution.
An expression is evaluated and compared to the "case"
expressions inside the "switch" to determine which branch
of the "switch" to execute.
A missing expression is equivalent to <code>true</code>.
</p>
<pre class="grammar"> <pre class="grammar">
SwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { CaseClause } "}" . SwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { CaseClause } "}" .
...@@ -3071,75 +3102,72 @@ CaseClause = SwitchCase ":" [ StatementList ] . ...@@ -3071,75 +3102,72 @@ CaseClause = SwitchCase ":" [ StatementList ] .
SwitchCase = "case" ExpressionList | "default" . SwitchCase = "case" ExpressionList | "default" .
</pre> </pre>
There can be at most one default case in a switch statement. In a case clause, <p>
the last statement only may be a fallthrough statement ($Fallthrough statement). The case expressions, which need not be constants,
It indicates that the control should flow from the end of this case clause to are evaluated top-to-bottom; the first one that matches
triggers execution of the statements of the associated case;
the other cases are skipped.
If no case matches and there is a "default" case, its statements are executed.
There can be at most one default case and it may appear anywhere in the
"switch" statement.
</p>
<p>
In a case or default clause,
the last statement only may be a "fallthrough" statement
($Fallthrough statement) to
indicate that control should flow from the end of this clause to
the first statement of the next clause. the first statement of the next clause.
Otherwise control flows to the end of the "switch" statement.
</p>
<p> <p>
Each case clause effectively acts as a block for scoping purposes Each case clause effectively acts as a block for scoping purposes
($Declarations and scope rules). ($Declarations and scope rules).
</p>
<p> <p>
The expressions do not need to be constants. They will A "switch" statement may include a short variable declaration before the
be evaluated top to bottom until the first successful non-default case is reached. expression.
If none matches and there is a default case, the statements of the default The scope of the declared variables extends to the end of the "switch" statement
case are executed. and the variables are initialized once before the statement is entered.
</p>
<pre> <pre>
switch tag { switch tag {
default: s3() default: s3()
case 0, 1: s1() case 0, 1, 2, 3: s1()
case 2: s2() case 4, 5, 6, 7: s2()
}
</pre>
A switch statement may include the declaration of a single temporary variable.
The scope of the declared variable extends to the end of the switch statement, and
the variable is initialized once before the switch is entered.
<pre>
switch x := f(); true {
case x &lt; 0: return -x
default: return x
} }
</pre>
Cases do not fall through unless explicitly marked with a "fallthrough" statement.
<pre> switch x := f(); {
switch a { case x &lt; 0: return -x
case 1: default: return x
b();
fallthrough
case 2:
c();
} }
</pre>
If the expression is omitted, it is equivalent to "true".
<pre> switch { // missing expression means "true"
switch { case x < y: f1();
case x < y: f1(); case x < z: f2();
case x < z: f2(); case x == 4: f3();
case x == 4: f3();
} }
</pre> </pre>
<h3>For statements</h3> <h3>For statements</h3>
A for statement specifies repeated execution of a block. The iteration is <p>
controlled by a condition, a for clause, or a range clause. A "for" statement specifies repeated execution of a block. The iteration is
controlled by a condition, a "for" clause, or a "range" clause.
</p>
<pre class="grammar"> <pre class="grammar">
ForStat = "for" [ Condition | ForClause | RangeClause ] Block . ForStat = "for" [ Condition | ForClause | RangeClause ] Block .
Condition = Expression . Condition = Expression .
</pre> </pre>
In its simplest form, a for statement specifies the repeated execution of <p>
a block as long as a condition evaluates to true. The condition is evaluated In its simplest form, a "for" statement specifies the repeated execution of
before each iteration. The type of the condition expression must be boolean. a block as long as a boolean condition evaluates to true.
If the condition is absent, it is equivalent to "true". The condition is evaluated before each iteration.
If the condition is absent, it is equivalent to <code>true</code>.
</p>
<pre> <pre>
for a &lt; b { for a &lt; b {
...@@ -3147,10 +3175,15 @@ for a &lt; b { ...@@ -3147,10 +3175,15 @@ for a &lt; b {
} }
</pre> </pre>
A for statement with a for clause is also controlled by its condition, but <p>
additionally it may specify an init and post statement, such as an assignment, A "for" statement with a "for" clause is also controlled by its condition, but
an increment or decrement statement. The init statement may also be a (simple) additionally it may specify an <i>init</i>
variable declaration; no variables can be declared in the post statement. and a <i>post</i> statement, such as an assignment,
an increment or decrement statement. The init statement (but not the post
statement) may also be a short variable declaration; the scope of the variables
it declares ends at the end of the statement
($Declarations and scope rules).
</p>
<pre class="grammar"> <pre class="grammar">
ForClause = [ InitStat ] ";" [ Condition ] ";" [ PostStat ] . ForClause = [ InitStat ] ";" [ Condition ] ";" [ PostStat ] .
...@@ -3158,55 +3191,60 @@ InitStat = SimpleStat . ...@@ -3158,55 +3191,60 @@ InitStat = SimpleStat .
PostStat = SimpleStat . PostStat = SimpleStat .
</pre> </pre>
For instance, one may declare an iteration variable in the init statement:
<pre> <pre>
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
f(i) f(i)
} }
</pre> </pre>
If present, the init statement is executed once before commencing the iteration;
the post statement is executed after each execution of the statement block (and
only if the block was executed). The scope of any variable declared in the init
statement ends with the end of the for statement block ($Declarations and scope
rules, Rule 3).
<p> <p>
The init and post statement as well as the condition may be omitted; however If non-empty, the init statement is executed once before evaluating the
if either the init or post statement are present, the separating semicolons condition for the first iteration;
must be present. If the condition is absent, it is equivalent to "true". the post statement is executed after each execution of the block (and
The following statements are equivalent: only if the block was executed).
Any element of the "for" clause may be empty but the semicolons are
required unless there is only a condition.
If the condition is absent, it is equivalent to <code>true</code>.
</p>
<pre> <pre>
for ; cond ; { S() } is the same as for cond { S() } for ; cond ; { S() } is the same as for cond { S() }
for true { S() } is the same as for { S() } for true { S() } is the same as for { S() }
</pre> </pre>
Alternatively, a for statement may be controlled by a range clause. A <p>
range clause specifies iteration through all entries of an array or map. A "for" statement with a "range" clause
iterates through all entries of an array, slice or map.
For each entry it first assigns the current index or key to an iteration For each entry it first assigns the current index or key to an iteration
variable - or the current (index, element) or (key, value) pair to a pair variable - or the current (index, element) or (key, value) pair to a pair
of iteration variables - and then executes the block. Iteration terminates of iteration variables - and then executes the block.
when all entries have been processed, or if the for statement is terminated </p>
early, for instance by a break or return statement.
<pre class="grammar"> <pre class="grammar">
RangeClause = IdentifierList ( "=" | ":=" ) "range" Expression . RangeClause = IdentifierList ( "=" | ":=" ) "range" Expression .
</pre> </pre>
The type of the right-hand expression in the range clause must be an array or <p>
map, or a pointer to an array or map. If it is a pointer, it must not be nil. The type of the right-hand expression in the "range" clause must be an array,
The left-hand identifier list must contain one or two identifiers denoting the slice or map, or a pointer to an array, slice or map.
iteration variables. The first variable is set to the current array index or The slice or map must not be <code>nil</code>.
The identifier list must contain one or two identifiers denoting the
iteration variables. On each iteration,
the first variable is set to the array or slice index or
map key, and the second variable, if present, is set to the corresponding map key, and the second variable, if present, is set to the corresponding
array element or map value. The types of the array index (int) and element, array element or map value.
or of the map key and value respectively, must be assignment-compatible to The types of the array or slice index (always <code>int</code>)
the iteration variables. and element, or of the map key and value respectively,
must be assignment compatible to the iteration variables.
</p>
<p> <p>
The iteration variables may be declared by the range clause (":="), in which The iteration variables may be declared by the "range" clause (":="), in which
case their scope ends at the end of the for statement block ($Declarations and case their scope ends at the end of the "for" statement ($Declarations and
scope rules, Rule 3). In this case their types are the array index and element, scope rules). In this case their types are set to
or the map key and value types, respectively. the array index and element types, or the map key and value types, respectively.
If the iteration variables are declared outside the "for" statement,
after execution their values will be those of the last iteration.
</p>
<pre> <pre>
var a [10]string; var a [10]string;
...@@ -3228,27 +3266,31 @@ for key, value = range m { ...@@ -3228,27 +3266,31 @@ for key, value = range m {
// val == map[key] // val == map[key]
</pre> </pre>
<p>
If map entries that have not yet been processed are deleted during iteration, If map entries that have not yet been processed are deleted during iteration,
they will not be processed. If map entries are inserted during iteration, the they will not be processed. If map entries are inserted during iteration, the
behavior is implementation-dependent. Likewise, if the range expression is a behavior is implementation-dependent. Likewise, if the range variable is
pointer variable, the behavior of assigning to that variable is implementation- assigned to during execution of the loop, the behavior is implementation-
dependent. Assigning to the iteration variables during iteration simply changes dependent.
the values of those variables for the current iteration; it does not affect any </p>
subsequent iterations.
<h3>Go statements</h3> <h3>Go statements</h3>
A go statement starts the execution of a function as an independent <p>
concurrent thread of control within the same address space. The expression A "go" statement starts the execution of a function or method call
must be a function or method call. as an independent concurrent thread of control, or <i>goroutine</i>,
within the same address space.
</p>
<pre class="grammar"> <pre class="grammar">
GoStat = "go" Expression . GoStat = "go" Expression .
</pre> </pre>
Unlike with a regular function call, program execution does not wait <p>
The expression must be a call, and
unlike with a regular call, program execution does not wait
for the invoked function to complete. for the invoked function to complete.
</p>
<pre> <pre>
go Server() go Server()
...@@ -3258,9 +3300,11 @@ go func(ch chan <- bool) { for { sleep(10); ch <- true; }} (c) ...@@ -3258,9 +3300,11 @@ go func(ch chan <- bool) { for { sleep(10); ch <- true; }} (c)
<h3>Select statements</h3> <h3>Select statements</h3>
A select statement chooses which of a set of possible communications <p>
will proceed. It looks similar to a switch statement but with the A "select" statement chooses which of a set of possible communications
will proceed. It looks similar to a "switch" statement but with the
cases all referring to communication operations. cases all referring to communication operations.
</p>
<pre class="grammar"> <pre class="grammar">
SelectStat = "select" "{" { CommClause } "}" . SelectStat = "select" "{" { CommClause } "}" .
...@@ -3270,35 +3314,43 @@ SendExpr = Expression "&lt;-" Expression . ...@@ -3270,35 +3314,43 @@ SendExpr = Expression "&lt;-" Expression .
RecvExpr = [ Expression ( "=" | ":=" ) ] "&lt;-" Expression . RecvExpr = [ Expression ( "=" | ":=" ) ] "&lt;-" Expression .
</pre> </pre>
<p>
Each communication clause acts as a block for the purpose of scoping Each communication clause acts as a block for the purpose of scoping
(§Declarations and scope rules). (§Declarations and scope rules).
</p>
<p> <p>
For all the send and receive expressions in the select For all the send and receive expressions in the "select"
statement, the channel expression is evaluated. Any values statement, the channel expression is evaluated. Any expressions
that appear on the right hand side of send expressions are also that appear on the right hand side of send expressions are also
evaluated. If any of the resulting channels can proceed, one is evaluated. If any of the resulting channels can proceed, one is
chosen and the corresponding communication and statements are chosen and the corresponding communication and statements are
evaluated. Otherwise, if there is a default case, that executes; evaluated. Otherwise, if there is a default case, that executes;
if not, the statement blocks until one of the communications can if not, the statement blocks until one of the communications can
complete. The channels and send expressions are not re-evaluated. complete. The channels and send expressions are not re-evaluated.
A channel pointer may be nil, which is equivalent to that case not A channel pointer may be <code>nil</code>,
being present in the select statement. which is equivalent to that case not
being present in the select statement
except, if a send, its expression is still evaluated.
</p>
<p> <p>
Since all the channels and send expressions are evaluated, any side Since all the channels and send expressions are evaluated, any side
effects in that evaluation will occur for all the communications effects in that evaluation will occur for all the communications
in the select. in the "select" statement.
</p>
<p> <p>
If the channel sends or receives an interface type, its If the channel sends or receives an interface type, its
communication can proceed only if the type of the communication communication can proceed only if the type of the communication
clause matches that of the dynamic value to be exchanged. clause matches that of the dynamic value to be exchanged.
</p>
<p> <p>
If multiple cases can proceed, a uniform fair choice is made regarding If multiple cases can proceed, a uniform fair choice is made to decide
which single communication will execute. which single communication will execute.
<p> <p>
The receive case may declare a new variable (via a ":=" assignment). The The receive case may declare a new variable using a short variable declaration
scope of such variables begins immediately after the variable identifier (§Short variable declarations).
and ends at the end of the respective "select" case (that is, before the The scope of such variables continues to the end of the
next "case", "default", or closing brace). respective case's statements.
</p>
<pre> <pre>
var c, c1, c2 chan int; var c, c1, c2 chan int;
...@@ -3337,60 +3389,86 @@ TODO: Make semantics more precise. ...@@ -3337,60 +3389,86 @@ TODO: Make semantics more precise.
<h3>Return statements</h3> <h3>Return statements</h3>
A return statement terminates execution of the containing function <p>
A "return" statement terminates execution of the containing function
and optionally provides a result value or values to the caller. and optionally provides a result value or values to the caller.
</p>
<pre class="grammar"> <pre class="grammar">
ReturnStat = "return" [ ExpressionList ] . ReturnStat = "return" [ ExpressionList ] .
</pre> </pre>
<pre>
func procedure() {
return
}
</pre>
There are two ways to return values from a function. The first is to <p>
explicitly list the return value or values in the return statement: There are two ways to return values from a function with a result
type. The first is to explicitly list the return value or values
in the "return" statement. The expressions
must be single-valued and assignment-compatible to the elements of
the result type of the function.
</p>
<pre> <pre>
func simple_f() int { func simple_f() int {
return 2; return 2
}
func complex_f1() (re float, im float) {
return -7.0, -4.0
} }
</pre> </pre>
A function may return multiple values. <p>
The syntax of the return clause in that case is the same as However, if the expression list in the "return" statement is a single call
that of a parameter list; in particular, names must be provided for to a multi-valued function, the values returned from the called function
the elements of the return value. will be returned from this one. The result types of the current function
and the called function must match.
</p>
<pre> <pre>
func complex_f1() (re float, im float) { func complex_f2() (re float, im float) {
return -7.0, -4.0; return complex_f1()
} }
</pre> </pre>
A second method to return values <p>
is to use those names within the function as variables Another method to return values is to use the elements of the
to be assigned explicitly; the return statement will then provide no result list of the function as variables. When the function begins
values: execution, these variables are initialized to the zero values for
their type (§The zero value). The function can assign them as
necessary; if the "return" provides no values, those of the variables
will be returned to the caller.
</p>
<pre> <pre>
func complex_f2() (re float, im float) { func complex_f3() (re float, im float) {
re = 7.0; re = 7.0;
im = 4.0; im = 4.0;
return; return;
} }
</pre> </pre>
<h3>Break statements</h3> <h3>Break statements</h3>
Within a for, switch, or select statement, a break statement terminates <p>
execution of the innermost such statement. A "break" statement terminates execution of the innermost
"for", "switch" or "select" statement.
</p>
<pre class="grammar"> <pre class="grammar">
BreakStat = "break" [ identifier ]. BreakStat = "break" [ Label ].
</pre> </pre>
If there is an identifier, it must be a label marking an enclosing <p>
for, switch, or select statement, and that is the one whose execution If there is a label, it must be that of an enclosing
terminates. "for", "switch" or "select" statement, and that is the one whose execution
terminates
(§For statements, §Switch statements, §Select statements).
</p>
<pre> <pre>
L: for i < n { L: for i < n {
...@@ -3400,49 +3478,40 @@ L: for i < n { ...@@ -3400,49 +3478,40 @@ L: for i < n {
} }
</pre> </pre>
<h3>Continue statements</h3> <h3>Continue statements</h3>
Within a for loop a continue statement begins the next iteration of the <p>
loop at the post statement. A "continue" statement begins the next iteration of the
innermost "for" loop at the post statement (§For statements).
<pre class="grammar"> </p>
ContinueStat = "continue" [ identifier ].
</pre>
The optional identifier is analogous to that of a break statement.
<h3>Label declarations</h3>
A label declaration serves as the target of a goto, break or continue statement.
<pre class="grammar"> <pre class="grammar">
LabelDecl = identifier ":" . ContinueStat = "continue" [ Label ].
</pre>
Example:
<pre>
Error:
</pre> </pre>
<p>
The optional label is analogous to that of a "break" statement.
</p>
<h3>Goto statements</h3> <h3>Goto statements</h3>
A goto statement transfers control to the corresponding label statement. <p>
A "goto" statement transfers control to the statement with the corresponding label.
</p>
<pre class="grammar"> <pre class="grammar">
GotoStat = "goto" identifier . GotoStat = "goto" Label .
</pre> </pre>
<pre> <pre>
goto Error goto Error
</pre> </pre>
Executing the goto statement must not cause any variables to come into <p>
Executing the "goto" statement must not cause any variables to come into
scope that were not already in scope at the point of the goto. For scope that were not already in scope at the point of the goto. For
instance, this example: instance, this example:
</p>
<pre> <pre>
goto L; // BAD goto L; // BAD
...@@ -3450,15 +3519,19 @@ v := 3; ...@@ -3450,15 +3519,19 @@ v := 3;
L: L:
</pre> </pre>
is erroneous because the jump to label L skips the creation of v. <p>
is erroneous because the jump to label <code>L</code> skips
the creation of <code>v</code>.
</p>
<h3>Fallthrough statements</h3> <h3>Fallthrough statements</h3>
A fallthrough statement transfers control to the first statement of the <p>
next case clause in a switch statement (§Switch statements). It may only A "fallthrough" statement transfers control to the first statement of the
be used in a switch statement, and only as the last statement in a case next case clause in a "switch" statement (§Switch statements). It may
clause of the switch statement. be used only as the lexically last statement in a case or default clause in a
"switch" statement.
</p>
<pre class="grammar"> <pre class="grammar">
FallthroughStat = "fallthrough" . FallthroughStat = "fallthrough" .
...@@ -3467,19 +3540,24 @@ FallthroughStat = "fallthrough" . ...@@ -3467,19 +3540,24 @@ FallthroughStat = "fallthrough" .
<h3>Defer statements</h3> <h3>Defer statements</h3>
A defer statement invokes a function whose execution is deferred to the moment <p>
when the surrounding function returns. A "defer" statement invokes a function whose execution is deferred to the moment
the surrounding function returns.
</p>
<pre class="grammar"> <pre class="grammar">
DeferStat = "defer" Expression . DeferStat = "defer" Expression .
</pre> </pre>
The expression must be a function or method call. Each time the defer statement <p>
The expression must be a function or method call.
Each time the "defer" statement
executes, the parameters to the function call are evaluated and saved anew but the executes, the parameters to the function call are evaluated and saved anew but the
function is not invoked. Immediately before the innermost function surrounding function is not invoked. Immediately before the innermost function surrounding
the defer statement returns, but after its return value (if any) is evaluated, the "defer" statement returns, but after its return value (if any) is evaluated,
each deferred function is executed with its saved parameters. Deferred functions each deferred function is executed with its saved parameters. Deferred functions
are executed in LIFO order. are executed in LIFO order.
</p>
<pre> <pre>
lock(l); lock(l);
...@@ -3539,55 +3617,66 @@ space allocated in the underlying array (for a slice) or map. For a slice ...@@ -3539,55 +3617,66 @@ space allocated in the underlying array (for a slice) or map. For a slice
<h3>Conversions</h3> <h3>Conversions</h3>
Conversions syntactically look like function calls of the form <p>
<font color=red>TODO: We need to finalize the details of conversions.</font>
<br/>
Conversions look like function calls of the form
</p>
<pre class="grammar"> <pre class="grammar">
T(value) T(value)
</pre> </pre>
<p>
where <code>T</code> is the type name of an arithmetic type or string (§Basic types), where <code>T</code> is the type name of an arithmetic type or string (§Basic types),
and <code>value</code> is the value of an expression that can be converted to a value and <code>value</code> is the value of an expression that can be converted to a value
of result type <code>T</code>. of result type <code>T</code>.
<p> <p>
The following conversion rules apply: The following conversion rules apply:
<p> </p>
<ul>
<li>
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 result 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, <code>uint32(int8(0xFF))</code> is <code>0xFFFFFFFF</code>.
yields a valid value; there is no signal for overflow. The conversion always yields a valid value; there is no signal for overflow.
<p> </li>
<li>
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
now it is defined as a ``best effort'' conversion. The conversion now it is defined as a ``best effort'' conversion. The conversion
always succeeds but the value may be a NaN or other problematic always succeeds but the value may be a NaN or other problematic
result. <font color=red>TODO: clarify?</font> result. <font color=red>TODO: clarify?</font>
<p> </li>
<li>
3) Strings permit two special conversions. 3) Strings permit two special conversions.
<p> </li>
<li>
3a) Converting an integer value yields a string containing the UTF-8 3a) Converting an integer value yields a string containing the UTF-8
representation of the integer. representation of the integer.
(TODO: this one could be done just as well by a library.) (TODO: this one could be done just as well by a library.)
</p>
<pre> <pre>
string(0x65e5) // "\u65e5" string(0x65e5) // "\u65e5"
</pre> </pre>
<p> </li>
3b) Converting an array of <code>uint8s</code> yields a string whose successive <li>
bytes are those of the array. 3b) Converting an array or slice of bytes yields a string whose successive
(Recall <code>byte</code> is a synonym for <code>uint8</code>.) bytes are those of the array/slice.
</p>
<pre> <pre>
string([]byte('h', 'e', 'l', 'l', 'o')) // "hello" string([]byte('h', 'e', 'l', 'l', 'o')) // "hello"
</pre> </pre>
</li>
</ul>
<p> <p>
There is no linguistic mechanism to convert between pointers There is no linguistic mechanism to convert between pointers and integers.
and integers. A library may be provided under restricted circumstances The <code>unsafe</code> package
to acccess this conversion in low-level code. implements this functionality under
restricted circumstances (§Package <code>unsafe</code>).
<font color=red> <font color=red>
TODO: Do we allow interface/ptr conversions in this form or do they TODO: Do we allow interface/ptr conversions in this form or do they
have to be written as type guards? (§Type guards) have to be written as type guards? (§Type guards)
...@@ -3597,52 +3686,66 @@ have to be written as type guards? (§Type guards) ...@@ -3597,52 +3686,66 @@ have to be written as type guards? (§Type guards)
<h3>Allocation</h3> <h3>Allocation</h3>
The built-in function "new" takes a type "T" and returns a value of type "*T". <p>
The built-in function <code>new</code> takes a type <code>T</code> and
returns a value of type <code>*T</code>.
The memory is initialized as described in the section on initial values The memory is initialized as described in the section on initial values
(§The zero value). (§The zero value).
</p>
<pre> <pre>
new(T) new(T)
</pre> </pre>
<p>
For instance For instance
</p>
<pre> <pre>
type S struct { a int; b float } type S struct { a int; b float }
new(S) new(S)
</pre> </pre>
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.
<p> <p>
<font color=red> dynamically allocates memory for a variable of type <code>S</code>,
TODO Once this has become clearer, connect new() and make() (new() may be initializes it (<code>a=0</code>, <code>b=0.0</code>),
explained by make() and vice versa). and returns a value of type <code>*S</code> containing the address
</font> of the memory.
</p>
<h3>Making slices, maps, and channels</h3> <h3>Making slices, maps and channels</h3>
The built-in function "make" takes a type "T", optionally followed by a <p>
type-specific list of expressions. It returns a value of type "T". "T" Slices, maps and channels are reference types that do not require the
must be a slice, map, or channel type. extra indirection of an allocation with <code>new</code>.
The built-in function <code>make</code> takes a type <code>T</code>,
which must be a slice, map or channel type,
optionally followed by a type-specific list of expressions.
It returns a value of type <code>T</code> (not <code>*T</code>).
The memory is initialized as described in the section on initial values The memory is initialized as described in the section on initial values
(§The zero value). (§The zero value).
</p>
<pre> <pre>
make(T [, optional list of expressions]) make(T [, optional list of expressions])
</pre> </pre>
<p>
For instance For instance
</p>
<pre> <pre>
make(map[string] int) make(map[string] int)
</pre> </pre>
<p>
creates a new map value and initializes it to an empty map. creates a new map value and initializes it to an empty map.
</p>
The only defined parameters affect sizes for allocating slices, maps, and <p>
The parameters affect sizes for allocating slices, maps, and
buffered channels: buffered channels:
</p>
<pre> <pre>
s := make([]int, 10, 100); # slice with len(s) == 10, cap(s) == 100 s := make([]int, 10, 100); # slice with len(s) == 10, cap(s) == 100
...@@ -3650,11 +3753,6 @@ c := make(chan int, 10); # channel with a buffer size of 10 ...@@ -3650,11 +3753,6 @@ 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 m := make(map[string] int, 100); # map with initial space for 100 elements
</pre> </pre>
<font color=red>
TODO Once this has become clearer, connect new() and make() (new() may be
explained by make() and vice versa).
</font>
<hr/> <hr/>
<h2>Packages</h2> <h2>Packages</h2>
...@@ -3743,7 +3841,7 @@ func generate(ch chan <- int) { ...@@ -3743,7 +3841,7 @@ func generate(ch chan <- int) {
// Copy the values from channel 'in' to channel 'out', // Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'. // removing those divisible by 'prime'.
func filter(in chan <- int, out *<-chan int, prime int) { func filter(in chan <- int, out <-chan int, prime int) {
for { for {
i := <-in; // Receive value of new variable 'i' from 'in'. i := <-in; // Receive value of new variable 'i' from 'in'.
if i % prime != 0 { if i % prime != 0 {
...@@ -3813,29 +3911,44 @@ t.f == 0.0 ...@@ -3813,29 +3911,44 @@ t.f == 0.0
t.next == nil t.next == nil
</pre> </pre>
<p>
The same would also be true after
</p>
<pre>
var t T
</pre>
<h3>Program execution</h3> <h3>Program execution</h3>
<p> <p>
A package with no imports is initialized by assigning initial values to A package with no imports is initialized by assigning initial values to
all its global variables in declaration order and then calling any init() all its package-level variables in declaration order and then calling any
functions defined in its source. Since a package may contain more package-level function with the name and signature of
than one source file, there may be more than one init() function, but </p>
<pre>
func init()
</pre>
<p>
defined in its source. Since a package may contain more
than one source file, there may be more than one
<code>init()</code> function in a package, but
only one per source file. only one per source file.
</p> </p>
<p> <p>
Initialization code may contain "go" statements, but the functions Initialization code may contain "go" statements, but the functions
they invoke do not begin execution until initialization of the entire they invoke do not begin execution until initialization of the entire
program is complete. Therefore, all initialization code is run in a single program is complete. Therefore, all initialization code is run in a single
thread of execution. goroutine.
</p> </p>
<p> <p>
Furthermore, an "init()" function cannot be referred to from anywhere An <code>init()</code> function cannot be referred to from anywhere
in a program. In particular, "init()" cannot be called explicitly, nor in a program. In particular, <code>init()</code> cannot be called explicitly,
can a pointer to "init" be assigned to a function variable). nor can a pointer to <code>init</code> be assigned to a function variable.
</p> </p>
<p> <p>
If a package has imports, the imported packages are initialized If a package has imports, the imported packages are initialized
before initializing the package itself. If multiple packages import before initializing the package itself. If multiple packages import
a package P, P will be initialized only once. a package <code>P</code>, <code>P</code> will be initialized only once.
</p> </p>
<p> <p>
The importing of packages, by construction, guarantees that there can The importing of packages, by construction, guarantees that there can
...@@ -3843,7 +3956,7 @@ be no cyclic dependencies in initialization. ...@@ -3843,7 +3956,7 @@ be no cyclic dependencies in initialization.
</p> </p>
<p> <p>
A complete program, possibly created by linking multiple packages, A complete program, possibly created by linking multiple packages,
must have one package called main, with a function must have one package called <code>main</code>, with a function
</p> </p>
<pre> <pre>
...@@ -3851,11 +3964,11 @@ func main() { ... } ...@@ -3851,11 +3964,11 @@ func main() { ... }
</pre> </pre>
<p> <p>
defined. The function <code>main.main()</code> takes no arguments and returns no defined.
value. The function <code>main.main()</code> takes no arguments and returns no value.
</p> </p>
<p> <p>
Program execution begins by initializing the main package and then Program execution begins by initializing the <code>main</code> package and then
invoking <code>main.main()</code>. invoking <code>main.main()</code>.
</p> </p>
<p> <p>
...@@ -3869,10 +3982,11 @@ When main.main() returns, the program exits. ...@@ -3869,10 +3982,11 @@ When main.main() returns, the program exits.
<h3>Package <code>unsafe</code></h3> <h3>Package <code>unsafe</code></h3>
<p> <p>
The built-in package <code>unsafe</code>, known to the compiler, provides facilities The built-in package <code>unsafe</code>, known to the compiler,
for low-level programming including operations that violate the type provides facilities for low-level programming including operations
system. A package using <code>unsafe</code> must be vetted manually for type safety. that violate the type system. A package using <code>unsafe</code>
The package provides the following interface: must be vetted manually for type safety. The package provides the
following interface:
</p> </p>
<pre class="grammar"> <pre class="grammar">
...@@ -3975,6 +4089,8 @@ cap() does not work on maps or chans. ...@@ -3975,6 +4089,8 @@ cap() does not work on maps or chans.
<br/> <br/>
len() does not work on chans. len() does not work on chans.
<br/> <br/>
select doesn't check dynamic type of interfaces.
<br/>
Conversions work for any type; doc says only arithmetic types and strings. Conversions work for any type; doc says only arithmetic types and strings.
</font> </font>
</p> </p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment