mirror of
https://github.com/golang/go
synced 2024-11-25 04:57:56 -07:00
go spec: follow-up cleanups after communication operator changes
These are syntactical changes to better reflect the communication operator's new status in the language. - sending to a channel is now done via a send statement - there is no binary communication operation anymore which leads to a reduction of the number of precedence levels from 6 to 5 (yeah!) - small semantic change: since a send operation is not part of the expression syntax anymore, a <- send operator is binding weaker than any other operator now - receiving from a channel is done as before via the unary receive expression - communication clauses in select statement now can contain send statements or receive expressions R=rsc, r, iant, ken2, gri1 CC=golang-dev https://golang.org/cl/3973051
This commit is contained in:
parent
dc9a02fa66
commit
b50ed022f5
121
doc/go_spec.html
121
doc/go_spec.html
@ -1,5 +1,5 @@
|
|||||||
<!-- title The Go Programming Language Specification -->
|
<!-- title The Go Programming Language Specification -->
|
||||||
<!-- subtitle Version of January 27, 2011 -->
|
<!-- subtitle Version of February 1, 2011 -->
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
TODO
|
TODO
|
||||||
@ -2667,9 +2667,7 @@ Operators combine operands into expressions.
|
|||||||
Expression = UnaryExpr | Expression binary_op UnaryExpr .
|
Expression = UnaryExpr | Expression binary_op UnaryExpr .
|
||||||
UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
|
UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
|
||||||
|
|
||||||
binary_op = log_op | com_op | rel_op | add_op | mul_op .
|
binary_op = "||" | "&&" | rel_op | add_op | mul_op .
|
||||||
log_op = "||" | "&&" .
|
|
||||||
com_op = "<-" .
|
|
||||||
rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" .
|
rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" .
|
||||||
add_op = "+" | "-" | "|" | "^" .
|
add_op = "+" | "-" | "|" | "^" .
|
||||||
mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
|
mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
|
||||||
@ -2726,18 +2724,17 @@ statements, not expressions, they fall
|
|||||||
outside the operator hierarchy.
|
outside the operator hierarchy.
|
||||||
As a consequence, statement <code>*p++</code> is the same as <code>(*p)++</code>.
|
As a consequence, statement <code>*p++</code> is the same as <code>(*p)++</code>.
|
||||||
<p>
|
<p>
|
||||||
There are six precedence levels for binary operators.
|
There are five precedence levels for binary operators.
|
||||||
Multiplication operators bind strongest, followed by addition
|
Multiplication operators bind strongest, followed by addition
|
||||||
operators, comparison operators, <code><-</code> (channel send),
|
operators, comparison operators, <code>&&</code> (logical and),
|
||||||
<code>&&</code> (logical and), and finally <code>||</code> (logical or):
|
and finally <code>||</code> (logical or):
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre class="grammar">
|
<pre class="grammar">
|
||||||
Precedence Operator
|
Precedence Operator
|
||||||
6 * / % << >> & &^
|
5 * / % << >> & &^
|
||||||
5 + - | ^
|
4 + - | ^
|
||||||
4 == != < <= > >=
|
3 == != < <= > >=
|
||||||
3 <-
|
|
||||||
2 &&
|
2 &&
|
||||||
1 ||
|
1 ||
|
||||||
</pre>
|
</pre>
|
||||||
@ -3005,51 +3002,21 @@ to by <code>x</code>.
|
|||||||
*pf(x)
|
*pf(x)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h3 id="Communication_operators">Communication operators</h3>
|
|
||||||
|
<h3 id="Receive_operator">Receive operator</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The term <i>channel</i> means "value of <a href="#Channel_types">channel type</a>".
|
For an operand <code>ch</code> of <a href="#Channel_types">channel type</a>,
|
||||||
</p>
|
the value of the receive operation <code><-ch</code> is the value received
|
||||||
<p>
|
from the channel <code>ch</code>. The type of the value is the element type of
|
||||||
The send operation uses the binary operator "<-", which operates on
|
the channel. The expression blocks until a value is available.
|
||||||
a channel and a value (expression):
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
ch <- 3
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The send operation sends the value on the channel. Both the channel
|
|
||||||
and the expression are evaluated before communication begins.
|
|
||||||
Communication blocks until the send can proceed, at which point the
|
|
||||||
value is transmitted on the channel.
|
|
||||||
A send on an unbuffered channel can proceed if a receiver is ready.
|
|
||||||
A send on a buffered channel can proceed if there is room in the buffer.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The receive operation uses the prefix unary operator "<-".
|
|
||||||
The value of the expression is the value received, whose type
|
|
||||||
is the element type of the channel.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
<-ch
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The expression blocks until a value is available, which then can
|
|
||||||
be assigned to a variable or used like any other expression.
|
|
||||||
If the receive expression does not save the value, the value is
|
|
||||||
discarded.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
v1 := <-ch
|
v1 := <-ch
|
||||||
v2 = <-ch
|
v2 = <-ch
|
||||||
f(<-ch)
|
f(<-ch)
|
||||||
<-strobe // wait until clock pulse
|
<-strobe // wait until clock pulse and discard received value
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@ -3075,8 +3042,7 @@ because the channel is closed and empty (<code>false</code>).
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Except in a communications clause of a <a href="#Select_statements">select statement</a>,
|
Receiving from a <code>nil</code> channel causes a
|
||||||
sending or receiving from a <code>nil</code> channel causes a
|
|
||||||
<a href="#Run_time_panics">run-time panic</a>.
|
<a href="#Run_time_panics">run-time panic</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -3087,6 +3053,7 @@ need to be presented regarding send, receive, select, and goroutines.</span>
|
|||||||
</p>
|
</p>
|
||||||
--->
|
--->
|
||||||
|
|
||||||
|
|
||||||
<h3 id="Method_expressions">Method expressions</h3>
|
<h3 id="Method_expressions">Method expressions</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -3508,7 +3475,7 @@ Statement =
|
|||||||
FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
|
FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
|
||||||
DeferStmt .
|
DeferStmt .
|
||||||
|
|
||||||
SimpleStmt = EmptyStmt | ExpressionStmt | IncDecStmt | Assignment | ShortVarDecl .
|
SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
@ -3543,7 +3510,7 @@ Error: log.Crash("error encountered")
|
|||||||
<h3 id="Expression_statements">Expression statements</h3>
|
<h3 id="Expression_statements">Expression statements</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Function calls, method calls, and channel operations
|
Function calls, method calls, and receive operations
|
||||||
can appear in statement context.
|
can appear in statement context.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -3553,11 +3520,44 @@ ExpressionStmt = Expression .
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
f(x+y)
|
h(x+y)
|
||||||
|
f.Close()
|
||||||
<-ch
|
<-ch
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h3 id="Send_statements">Send statements</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A send statement sends a value on a channel.
|
||||||
|
The channel expression must be of <a href="#Channel_types">channel type</a>
|
||||||
|
and the type of the value must be <a href="#Assignability">assignable</a>
|
||||||
|
to the channel's element type.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre class="ebnf">
|
||||||
|
SendStmt = Channel "<-" Expression .
|
||||||
|
Channel = Expression .
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Both the channel and the value expression are evaluated before communication
|
||||||
|
begins. Communication blocks until the send can proceed, at which point the
|
||||||
|
value is transmitted on the channel.
|
||||||
|
A send on an unbuffered channel can proceed if a receiver is ready.
|
||||||
|
A send on a buffered channel can proceed if there is room in the buffer.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
ch <- 3
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Sending to a <code>nil</code> channel causes a
|
||||||
|
<a href="#Run_time_panics">run-time panic</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<h3 id="IncDec_statements">IncDec statements</h3>
|
<h3 id="IncDec_statements">IncDec statements</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -4076,18 +4076,19 @@ cases all referring to communication operations.
|
|||||||
<pre class="ebnf">
|
<pre class="ebnf">
|
||||||
SelectStmt = "select" "{" { CommClause } "}" .
|
SelectStmt = "select" "{" { CommClause } "}" .
|
||||||
CommClause = CommCase ":" { Statement ";" } .
|
CommClause = CommCase ":" { Statement ";" } .
|
||||||
CommCase = "case" ( SendExpr | RecvExpr) | "default" .
|
CommCase = "case" ( SendStmt | RecvStmt ) | "default" .
|
||||||
SendExpr = Expression "<-" Expression .
|
RecvStmt = [ Expression ( "=" | ":=" ) ] RecvExpr .
|
||||||
RecvExpr = [ Expression ( "=" | ":=" ) ] "<-" Expression .
|
RecvExpr = Expression .
|
||||||
</pre>
|
</pre>
|
||||||
<!-- TODO(rsc):
|
<!-- TODO(rsc):
|
||||||
RecvExpr = [ Expression [ "," Expression ] ( "=" | ":=" ) ] "<-" Expression .
|
RecvStmt = [ Expression [ "," Expression ] ( "=" | ":=" ) ] RecvExpr .
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
For all the send and receive expressions in the "select"
|
RecvExpr must be a <a href="#Receive_operator">receive operation</a>.
|
||||||
|
For all the cases in the "select"
|
||||||
statement, the channel expressions are evaluated in top-to-bottom order, along with
|
statement, the channel expressions are evaluated in top-to-bottom order, along with
|
||||||
any expressions that appear on the right hand side of send expressions.
|
any expressions that appear on the right hand side of send statements.
|
||||||
A channel may be <code>nil</code>,
|
A channel may be <code>nil</code>,
|
||||||
which is equivalent to that case not
|
which is equivalent to that case not
|
||||||
being present in the select statement
|
being present in the select statement
|
||||||
@ -4398,7 +4399,7 @@ sent values have been received, receive operations will return
|
|||||||
the zero value for the channel's type without blocking.
|
the zero value for the channel's type without blocking.
|
||||||
|
|
||||||
<!-- TODO(rsc): delete next sentence, replace with
|
<!-- TODO(rsc): delete next sentence, replace with
|
||||||
The multi-valued <a href="#Communication_operators">receive operation</a>
|
The multi-valued <a href="#Receive_operator">receive operation</a>
|
||||||
returns a received value along with an indication of whether the channel is closed.
|
returns a received value along with an indication of whether the channel is closed.
|
||||||
-->
|
-->
|
||||||
After at least one such zero value has been
|
After at least one such zero value has been
|
||||||
|
Loading…
Reference in New Issue
Block a user