Commit 130ac740 authored by Robert Griesemer's avatar Robert Griesemer

Spec modified to reflect new semicolon rules.

R=rsc, r, iant, ken2
CC=golang-dev
https://golang.org/cl/166066
parent 57909b54
...@@ -126,12 +126,27 @@ hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" . ...@@ -126,12 +126,27 @@ hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
<h3 id="Comments">Comments</h3> <h3 id="Comments">Comments</h3>
<p> <p>
There are two forms of comments. The first starts at the character There are two forms of comments:
sequence <code>//</code> and continues through the next newline. The
second starts at the character sequence <code>/*</code> and continues
through the character sequence <code>*/</code>. Comments do not nest.
</p> </p>
<ol>
<li>
<i>Line comments</i> start with the character sequence <code>//</code>
and continue through the next newline. A line comment acts like a newline.
</li>
<li>
<i>General comments</i> start with the character sequence <code>/*</code>
and continue through the character sequence <code>*/</code>. A general
comment that spans multiple lines acts like a newline, otherwise it acts
like a space.
</li>
</ol>
<p>
Comments do not nest.
</p>
<h3 id="Tokens">Tokens</h3> <h3 id="Tokens">Tokens</h3>
<p> <p>
...@@ -141,12 +156,52 @@ and delimiters, and literals. <i>White space</i>, formed from ...@@ -141,12 +156,52 @@ and delimiters, and literals. <i>White space</i>, formed from
spaces (U+0020), horizontal tabs (U+0009), spaces (U+0020), horizontal tabs (U+0009),
carriage returns (U+000D), and newlines (U+000A), carriage returns (U+000D), and newlines (U+000A),
is ignored except as it separates tokens is ignored except as it separates tokens
that would otherwise combine into a single token. Comments that would otherwise combine into a single token.
behave as white space. While breaking the input into tokens, While breaking the input into tokens,
the next token is the longest sequence of characters that form a the next token is the longest sequence of characters that form a
valid token. valid token.
</p> </p>
<h3 id="Semicolons">Semicolons</h3>
<p>
The formal grammar uses semicolons <code>";"</code> as terminators in
a number of productions. Go programs may omit most of these semicolons
using the following two rules:
</p>
<ol>
<li>
<p>
When the input is broken into tokens, a semicolon is automatically inserted
into the token stream at the end of a non-blank line if the line's final
token is
</p>
<ul>
<li>an identifier or basic literal
<li>one of the keywords
<code>break</code>, <code>continue</code>, <code>fallthrough</code>,
or <code>return</code>
</li>
<li>one of the operators and delimiters
<code>++</code>, <code>--</code>, <code>)</code>, <code>]</code>,
or <code>}</code>
</li>
</ul>
</li>
<li>
To allow complex statements to occupy a single line, a semicolon
may be omitted before a closing <code>")"</code> or <code>"}"</code>.
</li>
</ol>
<p>
To reflect idiomatic use, code examples in this document elide semicolons
using these rules.
</p>
<h3 id="Identifiers">Identifiers</h3> <h3 id="Identifiers">Identifiers</h3>
<p> <p>
...@@ -163,7 +218,11 @@ _x9 ...@@ -163,7 +218,11 @@ _x9
ThisVariableIsExported ThisVariableIsExported
αβ αβ
</pre> </pre>
<p>
Some identifiers are <a href="#Predeclared_identifiers">predeclared</a>. Some identifiers are <a href="#Predeclared_identifiers">predeclared</a>.
</p>
<h3 id="Keywords">Keywords</h3> <h3 id="Keywords">Keywords</h3>
...@@ -359,12 +418,7 @@ the two bytes <code>0xc3</code> <code>0xbf</code> of the UTF-8 encoding of chara ...@@ -359,12 +418,7 @@ the two bytes <code>0xc3</code> <code>0xbf</code> of the UTF-8 encoding of chara
U+00FF. U+00FF.
</p> </p>
<p>
A sequence of string literals is concatenated to form a single string constant.
</p>
<pre class="ebnf"> <pre class="ebnf">
StringLit = string_lit { string_lit } .
string_lit = raw_string_lit | interpreted_string_lit . string_lit = raw_string_lit | interpreted_string_lit .
raw_string_lit = "`" { unicode_char } "`" . raw_string_lit = "`" { unicode_char } "`" .
interpreted_string_lit = `"` { unicode_value | byte_value } `"` . interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
...@@ -380,8 +434,6 @@ interpreted_string_lit = `"` { unicode_value | byte_value } `"` . ...@@ -380,8 +434,6 @@ interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
"日本語" "日本語"
"\u65e5本\U00008a9e" "\u65e5本\U00008a9e"
"\xff\u00FF" "\xff\u00FF"
"Alea iacta est."
"Alea " /* The die */ `iacta est` /* is cast */ "." // same as "Alea iacta est."
</pre> </pre>
<p> <p>
...@@ -712,11 +764,10 @@ be unique. ...@@ -712,11 +764,10 @@ be unique.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
StructType = "struct" "{" [ FieldDeclList ] "}" . StructType = "struct" "{" { FieldDecl ";" } "}" .
FieldDeclList = FieldDecl { ";" FieldDecl } [ ";" ] .
FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] . FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] .
AnonymousField = [ "*" ] TypeName . AnonymousField = [ "*" ] TypeName .
Tag = StringLit . Tag = string_lit .
</pre> </pre>
<pre> <pre>
...@@ -725,11 +776,11 @@ struct {} ...@@ -725,11 +776,11 @@ struct {}
// A struct with 6 fields. // A struct with 6 fields.
struct { struct {
x, y int; x, y int
u float; u float
_ float; // padding _ float // padding
A *[]int; A *[]int
F func(); F func()
} }
</pre> </pre>
...@@ -744,11 +795,11 @@ a pointer type. The unqualified type name acts as the field name. ...@@ -744,11 +795,11 @@ a pointer type. The unqualified type name acts as the field name.
<pre> <pre>
// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4 // A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
struct { struct {
T1; // field name is T1 T1 // field name is T1
*T2; // field name is T2 *T2 // field name is T2
P.T3; // field name is T3 P.T3 // field name is T3
*P.T4; // field name is T4 *P.T4 // field name is T4
x, y int; // field names are x and y x, y int // field names are x and y
} }
</pre> </pre>
...@@ -759,9 +810,9 @@ in a struct type: ...@@ -759,9 +810,9 @@ in a struct type:
<pre> <pre>
struct { struct {
T; // conflicts with anonymous field *T and *P.T T // conflicts with anonymous field *T and *P.T
*T; // conflicts with anonymous field T and *P.T *T // conflicts with anonymous field T and *P.T
*P.T; // conflicts with anonymous field T and *T *P.T // conflicts with anonymous field T and *T
} }
</pre> </pre>
...@@ -799,9 +850,9 @@ but are otherwise ignored. ...@@ -799,9 +850,9 @@ but are otherwise ignored.
// A struct corresponding to the TimeStamp protocol buffer. // A struct corresponding to the TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers. // The tag strings define the protocol buffer field numbers.
struct { struct {
microsec uint64 "field 1"; microsec uint64 "field 1"
serverIP6 uint64 "field 2"; serverIP6 uint64 "field 2"
process string "field 3"; process string "field 3"
} }
</pre> </pre>
...@@ -835,7 +886,7 @@ A function value may be <code>nil</code>. ...@@ -835,7 +886,7 @@ A function value may be <code>nil</code>.
FunctionType = "func" Signature . FunctionType = "func" Signature .
Signature = Parameters [ Result ] . Signature = Parameters [ Result ] .
Result = Parameters | Type . Result = Parameters | Type .
Parameters = "(" [ ParameterList ] ")" . Parameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = ParameterDecl { "," ParameterDecl } . ParameterList = ParameterDecl { "," ParameterDecl } .
ParameterDecl = [ IdentifierList ] ( Type | "..." ) . ParameterDecl = [ IdentifierList ] ( Type | "..." ) .
</pre> </pre>
...@@ -878,8 +929,7 @@ that is any superset of the interface. Such a type is said to ...@@ -878,8 +929,7 @@ that is any superset of the interface. Such a type is said to
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
InterfaceType = "interface" "{" [ MethodSpecList ] "}" . InterfaceType = "interface" "{" { MethodSpec ";" } "}" .
MethodSpecList = MethodSpec { ";" MethodSpec } [ ";" ] .
MethodSpec = MethodName Signature | InterfaceTypeName . MethodSpec = MethodName Signature | InterfaceTypeName .
MethodName = identifier . MethodName = identifier .
InterfaceTypeName = TypeName . InterfaceTypeName = TypeName .
...@@ -892,9 +942,9 @@ As with all method sets, in an interface type, each method must have a unique na ...@@ -892,9 +942,9 @@ As with all method sets, in an interface type, each method must have a unique na
<pre> <pre>
// A simple File interface // A simple File interface
interface { interface {
Read(b Buffer) bool; Read(b Buffer) bool
Write(b Buffer) bool; Write(b Buffer) bool
Close(); Close()
} }
</pre> </pre>
...@@ -935,8 +985,8 @@ to define an interface called <code>Lock</code>: ...@@ -935,8 +985,8 @@ to define an interface called <code>Lock</code>:
<pre> <pre>
type Lock interface { type Lock interface {
Lock(); Lock()
Unlock(); Unlock()
} }
</pre> </pre>
...@@ -962,14 +1012,14 @@ in the interface. ...@@ -962,14 +1012,14 @@ in the interface.
<pre> <pre>
type ReadWrite interface { type ReadWrite interface {
Read(b Buffer) bool; Read(b Buffer) bool
Write(b Buffer) bool; Write(b Buffer) bool
} }
type File interface { type File interface {
ReadWrite; // same as enumerating the methods in ReadWrite ReadWrite // same as enumerating the methods in ReadWrite
Lock; // same as enumerating the methods in Lock Lock // same as enumerating the methods in Lock
Close(); Close()
} }
</pre> </pre>
...@@ -1144,12 +1194,12 @@ Given the declarations ...@@ -1144,12 +1194,12 @@ Given the declarations
<pre> <pre>
type ( type (
T0 []string; T0 []string
T1 []string; T1 []string
T2 struct { a, b int }; T2 struct { a, b int }
T3 struct { a, c int }; T3 struct { a, c int }
T4 func (int, float) *T0; T4 func (int, float) *T0
T5 func (x int, y float) *[]string; T5 func (x int, y float) *[]string
) )
</pre> </pre>
...@@ -1297,7 +1347,7 @@ brace brackets. ...@@ -1297,7 +1347,7 @@ brace brackets.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
Block = "{" StatementList "}" . Block = "{" { Statement ";" } "}" .
</pre> </pre>
<p> <p>
...@@ -1459,8 +1509,7 @@ right. ...@@ -1459,8 +1509,7 @@ right.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
ConstDecl = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) . ConstDecl = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
ConstSpecList = ConstSpec { ";" ConstSpec } [ ";" ] .
ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] . ConstSpec = IdentifierList [ [ Type ] "=" ExpressionList ] .
IdentifierList = identifier { "," identifier } . IdentifierList = identifier { "," identifier } .
...@@ -1483,8 +1532,8 @@ constant, even if the literal's fractional part is zero. ...@@ -1483,8 +1532,8 @@ constant, even if the literal's fractional part is zero.
const Pi float64 = 3.14159265358979323846 const Pi float64 = 3.14159265358979323846
const zero = 0.0 // untyped floating-point constant const zero = 0.0 // untyped floating-point constant
const ( const (
size int64 = 1024; size int64 = 1024
eof = -1; // untyped integer constant eof = -1 // untyped integer constant
) )
const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", untyped integer and string constants const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo", untyped integer and string constants
const u, v float = 0, 3 // u = 0.0, v = 3.0 const u, v float = 0, 3 // u = 0.0, v = 3.0
...@@ -1504,14 +1553,14 @@ this mechanism permits light-weight declaration of sequential values: ...@@ -1504,14 +1553,14 @@ this mechanism permits light-weight declaration of sequential values:
<pre> <pre>
const ( const (
Sunday = iota; Sunday = iota
Monday; Monday
Tuesday; Tuesday
Wednesday; Wednesday
Thursday; Thursday
Friday; Friday
Partyday; Partyday
numberOfDays; // this constant is not exported numberOfDays // this constant is not exported
) )
</pre> </pre>
...@@ -1522,31 +1571,32 @@ const ( ...@@ -1522,31 +1571,32 @@ const (
Within a constant declaration, the predeclared identifier Within a constant declaration, the predeclared identifier
<code>iota</code> represents successive untyped integer <a href="#Constants"> <code>iota</code> represents successive untyped integer <a href="#Constants">
constants</a>. It is reset to 0 whenever the reserved word <code>const</code> constants</a>. It is reset to 0 whenever the reserved word <code>const</code>
appears in the source and increments with each semicolon. It can be used to construct a appears in the source and increments with each
<a href="#Semicolons">semicolon</a>. It can be used to construct a
set of related constants: set of related constants:
</p> </p>
<pre> <pre>
const ( // iota is reset to 0 const ( // iota is reset to 0
c0 = iota; // c0 == 0 c0 = iota // c0 == 0
c1 = iota; // c1 == 1 c1 = iota // c1 == 1
c2 = iota // c2 == 2 c2 = iota // c2 == 2
) )
const ( const (
a = 1 &lt;&lt; iota; // a == 1 (iota has been reset) a = 1 &lt;&lt; iota // a == 1 (iota has been reset)
b = 1 &lt;&lt; iota; // b == 2 b = 1 &lt;&lt; iota // b == 2
c = 1 &lt;&lt; iota; // c == 4 c = 1 &lt;&lt; iota // c == 4
) )
const ( const (
u = iota * 42; // u == 0 (untyped integer constant) u = iota * 42 // u == 0 (untyped integer constant)
v float = iota * 42; // v == 42.0 (float constant) v float = iota * 42 // v == 42.0 (float constant)
w = iota * 42; // w == 84 (untyped integer constant) w = iota * 42 // w == 84 (untyped integer constant)
) )
const x = iota; // x == 0 (iota has been reset) const x = iota // x == 0 (iota has been reset)
const y = iota; // y == 0 (iota has been reset) const y = iota // y == 0 (iota has been reset)
</pre> </pre>
<p> <p>
...@@ -1556,10 +1606,10 @@ it is only incremented at a semicolon: ...@@ -1556,10 +1606,10 @@ it is only incremented at a semicolon:
<pre> <pre>
const ( const (
bit0, mask0 = 1 &lt;&lt; iota, 1 &lt;&lt; iota - 1; // bit0 == 1, mask0 == 0 bit0, mask0 = 1 &lt;&lt; iota, 1 &lt;&lt; iota - 1 // bit0 == 1, mask0 == 0
bit1, mask1; // bit1 == 2, mask1 == 1 bit1, mask1 // bit1 == 2, mask1 == 1
_, _; // skips iota == 2 _, _ // skips iota == 2
bit3, mask3; // bit3 == 8, mask3 == 7 bit3, mask3 // bit3 == 8, mask3 == 7
) )
</pre> </pre>
...@@ -1580,8 +1630,7 @@ an existing type. The new type is ...@@ -1580,8 +1630,7 @@ an existing type. The new type is
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
TypeDecl = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) . TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] .
TypeSpec = identifier Type . TypeSpec = identifier Type .
</pre> </pre>
...@@ -1589,19 +1638,19 @@ TypeSpec = identifier Type . ...@@ -1589,19 +1638,19 @@ TypeSpec = identifier Type .
type IntArray [16]int type IntArray [16]int
type ( type (
Point struct { x, y float }; Point struct { x, y float }
Polar Point Polar Point
) )
type TreeNode struct { type TreeNode struct {
left, right *TreeNode; left, right *TreeNode
value *Comparable; value *Comparable
} }
type Cipher interface { type Cipher interface {
BlockSize() int; BlockSize() int
Encrypt(src, dst []byte); Encrypt(src, dst []byte)
Decrypt(src, dst []byte); Decrypt(src, dst []byte)
} }
</pre> </pre>
...@@ -1623,7 +1672,7 @@ type NewMutex Mutex ...@@ -1623,7 +1672,7 @@ type NewMutex Mutex
// PrintableMutex's method set contains the methods // PrintableMutex's method set contains the methods
// Lock and Unlock bound to its anonymous field Mutex. // Lock and Unlock bound to its anonymous field Mutex.
type PrintableMutex struct { type PrintableMutex struct {
Mutex; Mutex
} }
</pre> </pre>
...@@ -1636,14 +1685,14 @@ type and attach methods to it: ...@@ -1636,14 +1685,14 @@ type and attach methods to it:
type TimeZone int type TimeZone int
const ( const (
EST TimeZone = -(5 + iota); EST TimeZone = -(5 + iota)
CST; CST
MST; MST
PST; PST
) )
func (tz TimeZone) String() string { func (tz TimeZone) String() string {
return fmt.Sprintf("GMT+%dh", tz); return fmt.Sprintf("GMT+%dh", tz)
} }
</pre> </pre>
...@@ -1655,8 +1704,7 @@ A variable declaration creates a variable, binds an identifier to it and ...@@ -1655,8 +1704,7 @@ A variable declaration creates a variable, binds an identifier to it and
gives it a type and optionally an initial value. gives it a type and optionally an initial value.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
VarDecl = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) . VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
VarSpecList = VarSpec { ";" VarSpec } [ ";" ] .
VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) . VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
</pre> </pre>
...@@ -1666,11 +1714,11 @@ var U, V, W float ...@@ -1666,11 +1714,11 @@ var U, V, W float
var k = 0 var k = 0
var x, y float = -1, -2 var x, y float = -1, -2
var ( var (
i int; i int
u, v, s = 2.0, 3.0, "bar" u, v, s = 2.0, 3.0, "bar"
) )
var re, im = complexSqrt(-1) var re, im = complexSqrt(-1)
var _, found = entries[name]; // map lookup; only interested in "found" var _, found = entries[name] // map lookup; only interested in "found"
</pre> </pre>
<p> <p>
...@@ -1721,11 +1769,11 @@ initializer expressions but no types: ...@@ -1721,11 +1769,11 @@ initializer expressions but no types:
</pre> </pre>
<pre> <pre>
i, j := 0, 10; i, j := 0, 10
f := func() int { return 7; } f := func() int { return 7 }
ch := make(chan int); ch := make(chan int)
r, w := os.Pipe(fd); // os.Pipe() returns two values r, w := os.Pipe(fd) // os.Pipe() returns two values
_, y, _ := coord(p); // coord() returns three values; only interested in y coordinate _, y, _ := coord(p) // coord() returns three values; only interested in y coordinate
</pre> </pre>
<p> <p>
...@@ -1738,8 +1786,8 @@ variable; it just assigns a new value to the original. ...@@ -1738,8 +1786,8 @@ variable; it just assigns a new value to the original.
</p> </p>
<pre> <pre>
field1, offset := nextField(str, 0); field1, offset := nextField(str, 0)
field2, offset := nextField(str, offset); // redeclares offset field2, offset := nextField(str, offset) // redeclares offset
</pre> </pre>
<p> <p>
...@@ -1768,9 +1816,9 @@ signature for a function implemented outside Go, such as an assembly routine. ...@@ -1768,9 +1816,9 @@ signature for a function implemented outside Go, such as an assembly routine.
<pre> <pre>
func min(x int, y int) int { func min(x int, y int) int {
if x &lt; y { if x &lt; y {
return x; return x
} }
return y; return y
} }
func flushICache(begin, end uintptr) // implemented externally func flushICache(begin, end uintptr) // implemented externally
...@@ -1805,12 +1853,12 @@ Given type <code>Point</code>, the declarations ...@@ -1805,12 +1853,12 @@ Given type <code>Point</code>, the declarations
<pre> <pre>
func (p *Point) Length() float { func (p *Point) Length() float {
return Math.sqrt(p.x * p.x + p.y * p.y); return Math.sqrt(p.x * p.x + p.y * p.y)
} }
func (p *Point) Scale(factor float) { func (p *Point) Scale(factor float) {
p.x = p.x * factor; p.x = p.x * factor
p.y = p.y * factor; p.y = p.y * factor
} }
</pre> </pre>
...@@ -1856,7 +1904,7 @@ Operands denote the elementary values in an expression. ...@@ -1856,7 +1904,7 @@ Operands denote the elementary values in an expression.
<pre class="ebnf"> <pre class="ebnf">
Operand = Literal | QualifiedIdent | MethodExpr | "(" Expression ")" . Operand = Literal | QualifiedIdent | MethodExpr | "(" Expression ")" .
Literal = BasicLit | CompositeLit | FunctionLit . Literal = BasicLit | CompositeLit | FunctionLit .
BasicLit = int_lit | float_lit | char_lit | StringLit . BasicLit = int_lit | float_lit | char_lit | string_lit .
</pre> </pre>
...@@ -1897,10 +1945,10 @@ a single expression or a key-value pair. ...@@ -1897,10 +1945,10 @@ a single expression or a key-value pair.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
CompositeLit = LiteralType "{" [ ElementList ] "}" . CompositeLit = LiteralType "{" [ ElementList [ "," ] ] "}" .
LiteralType = StructType | ArrayType | "[" "..." "]" ElementType | LiteralType = StructType | ArrayType | "[" "..." "]" ElementType |
SliceType | MapType | TypeName | "(" LiteralType ")" . SliceType | MapType | TypeName | "(" LiteralType ")" .
ElementList = Element { "," Element } [ "," ] . ElementList = Element { "," Element } .
Element = [ Key ":" ] Value . Element = [ Key ":" ] Value .
Key = FieldName | ElementIndex . Key = FieldName | ElementIndex .
FieldName = identifier . FieldName = identifier .
...@@ -1959,8 +2007,8 @@ one may write ...@@ -1959,8 +2007,8 @@ one may write
</p> </p>
<pre> <pre>
origin := Point{}; // zero value for Point origin := Point{} // zero value for Point
line := Line{origin, Point{y: -4, z: 12.3}}; // zero value for line.q.x line := Line{origin, Point{y: -4, z: 12.3}} // zero value for line.q.x
</pre> </pre>
<p> <p>
...@@ -1983,7 +2031,7 @@ Taking the address of a composite literal (§<a href="#Address_operators">Addres ...@@ -1983,7 +2031,7 @@ Taking the address of a composite literal (§<a href="#Address_operators">Addres
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 pointer *Point = &amp;Point{y: 1000}; var pointer *Point = &amp;Point{y: 1000}
</pre> </pre>
<p> <p>
...@@ -1996,9 +2044,9 @@ to the maximum element index plus one. ...@@ -1996,9 +2044,9 @@ to the maximum element index plus one.
</p> </p>
<pre> <pre>
buffer := [10]string{}; // len(buffer) == 10 buffer := [10]string{} // len(buffer) == 10
intSet := [6]int{1, 2, 3, 5}; // len(intSet) == 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>
...@@ -2040,13 +2088,13 @@ Examples of valid array, slice, and map literals: ...@@ -2040,13 +2088,13 @@ Examples of valid array, slice, and map literals:
<pre> <pre>
// list of prime numbers // list of prime numbers
primes := []int{2, 3, 5, 7, 9, 11, 13, 17, 19, 991}; primes := []int{2, 3, 5, 7, 9, 11, 13, 17, 19, 991}
// vowels[ch] is true if ch is a vowel // vowels[ch] is true if ch is a vowel
vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}; 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}; // 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}; filter := [10]float{-1, 4: -0.1, -0.1, 9: -1}
// frequencies in Hz for equal-tempered scale (A4 = 440Hz) // frequencies in Hz for equal-tempered scale (A4 = 440Hz)
noteFrequency := map[string]float{ noteFrequency := map[string]float{
...@@ -2109,7 +2157,7 @@ Selector = "." identifier . ...@@ -2109,7 +2157,7 @@ Selector = "." identifier .
Index = "[" Expression "]" . Index = "[" Expression "]" .
Slice = "[" Expression ":" [ Expression ] "]" . Slice = "[" Expression ":" [ Expression ] "]" .
TypeAssertion = "." "(" Type ")" . TypeAssertion = "." "(" Type ")" .
Call = "(" [ ExpressionList ] ")" . Call = "(" [ ExpressionList [ "," ] ] ")" .
</pre> </pre>
...@@ -2200,26 +2248,26 @@ For example, given the declarations: ...@@ -2200,26 +2248,26 @@ For example, given the declarations:
<pre> <pre>
type T0 struct { type T0 struct {
x int; x int
} }
func (recv *T0) M0() func (recv *T0) M0()
type T1 struct { type T1 struct {
y int; y int
} }
func (recv T1) M1() func (recv T1) M1()
type T2 struct { type T2 struct {
z int; z int
T1; T1
*T0; *T0
} }
func (recv *T2) M2() func (recv *T2) M2()
var p *T2; // with p != nil and p.T1 != nil var p *T2 // with p != nil and p.T1 != nil
</pre> </pre>
<p> <p>
...@@ -2356,8 +2404,8 @@ After slicing the array <code>a</code> ...@@ -2356,8 +2404,8 @@ After slicing the array <code>a</code>
</p> </p>
<pre> <pre>
a := [5]int{1, 2, 3, 4, 5}; a := [5]int{1, 2, 3, 4, 5}
s := a[1:4]; s := a[1:4]
</pre> </pre>
<p> <p>
...@@ -2463,7 +2511,7 @@ the method. ...@@ -2463,7 +2511,7 @@ the method.
<pre> <pre>
math.Atan2(x, y) // function call math.Atan2(x, y) // function call
var pt *Point; var pt *Point
pt.Scale(3.5) // method call with receiver pt pt.Scale(3.5) // method call with receiver pt
</pre> </pre>
...@@ -2504,7 +2552,7 @@ for <code>(&amp;x).m()</code>: ...@@ -2504,7 +2552,7 @@ for <code>(&amp;x).m()</code>:
</p> </p>
<pre> <pre>
var p Point; var p Point
p.Scale(3.5) p.Scale(3.5)
</pre> </pre>
...@@ -2540,7 +2588,7 @@ Given the function and call ...@@ -2540,7 +2588,7 @@ Given the function and call
</p> </p>
<pre> <pre>
func Fprintf(f io.Writer, format string, args ...) func Fprintf(f io.Writer, format string, args ...)
Fprintf(os.Stdout, "%s %d", "hello", 23); Fprintf(os.Stdout, "%s %d", "hello", 23)
</pre> </pre>
<p> <p>
...@@ -2610,12 +2658,12 @@ the left operand alone. ...@@ -2610,12 +2658,12 @@ the left operand alone.
</p> </p>
<pre> <pre>
var s uint = 33; var s uint = 33
var i = 1&lt;&lt;s; // 1 has type int var i = 1&lt;&lt;s // 1 has type int
var j = int32(1&lt;&lt;s); // 1 has type int32; j == 0 var j = int32(1&lt;&lt;s) // 1 has type int32; j == 0
var u = uint64(1&lt;&lt;s); // 1 has type uint64; u == 1&lt;&lt;33 var u = uint64(1&lt;&lt;s) // 1 has type uint64; u == 1&lt;&lt;33
var f = float(1&lt;&lt;s); // illegal: 1 has type float, cannot shift var f = float(1&lt;&lt;s) // illegal: 1 has type float, cannot shift
var g = float(1&lt;&lt;33); // legal; 1&lt;&lt;33 is a constant shift operation; g == 1&lt;&lt;33 var g = float(1&lt;&lt;33) // legal; 1&lt;&lt;33 is a constant shift operation; g == 1&lt;&lt;33
</pre> </pre>
<h3 id="Operator_precedence">Operator precedence</h3> <h3 id="Operator_precedence">Operator precedence</h3>
...@@ -2688,8 +2736,8 @@ or the <code>+=</code> assignment operator: ...@@ -2688,8 +2736,8 @@ or the <code>+=</code> assignment operator:
</p> </p>
<pre> <pre>
s := "hi" + string(c); s := "hi" + string(c)
s += " and good bye"; s += " and good bye"
</pre> </pre>
<p> <p>
...@@ -2883,7 +2931,7 @@ These two examples are equivalent: ...@@ -2883,7 +2931,7 @@ These two examples are equivalent:
</p> </p>
<pre> <pre>
ok := ch &lt;- 3; ok := ch &lt;- 3
if ok { print("sent") } else { print("not sent") } if ok { print("sent") } else { print("not sent") }
if ch &lt;- 3 { print("sent") } else { print("not sent") } if ch &lt;- 3 { print("sent") } else { print("not sent") }
...@@ -2968,11 +3016,11 @@ Consider a struct type <code>T</code> with two methods, ...@@ -2968,11 +3016,11 @@ Consider a struct type <code>T</code> with two methods,
<pre> <pre>
type T struct { type T struct {
a int; a int
} }
func (tv T) Mv(a int) int { return 0 } // value receiver func (tv T) Mv(a int) int { return 0 } // value receiver
func (tp *T) Mp(f float) float { return 1 } // pointer receiver func (tp *T) Mp(f float) float { return 1 } // pointer receiver
var t T; var t T
</pre> </pre>
<p> <p>
...@@ -3190,8 +3238,8 @@ by any predeclared type in the language. The following are legal declarations: ...@@ -3190,8 +3238,8 @@ by any predeclared type in the language. The following are legal declarations:
</p> </p>
<pre> <pre>
const Huge = 1 &lt;&lt; 100; const Huge = 1 &lt;&lt; 100
const Four int8 = Huge &gt;&gt; 98; const Four int8 = Huge &gt;&gt; 98
</pre> </pre>
<p> <p>
...@@ -3277,20 +3325,8 @@ Statement = ...@@ -3277,20 +3325,8 @@ Statement =
DeferStmt . DeferStmt .
SimpleStmt = EmptyStmt | ExpressionStmt | IncDecStmt | Assignment | ShortVarDecl . SimpleStmt = EmptyStmt | ExpressionStmt | IncDecStmt | Assignment | ShortVarDecl .
StatementList = Statement { Separator Statement } .
Separator = [ ";" ] .
</pre> </pre>
<p>
Elements of a list of statements are separated by semicolons,
which may be omitted only if the previous statement:
</p>
<ul>
<li>ends with the closing parenthesis ")" of a list of <a href="#Declarations_and_scope">declarations</a>; or</li>
<li>ends with a closing brace "}" that is not part of an expression.
</ul>
<h3 id="Empty_statements">Empty statements</h3> <h3 id="Empty_statements">Empty statements</h3>
...@@ -3302,11 +3338,6 @@ The empty statement does nothing. ...@@ -3302,11 +3338,6 @@ The empty statement does nothing.
EmptyStmt = . EmptyStmt = .
</pre> </pre>
<p>
A statement list can always be terminated with a semicolon, in effect
adding an empty statement.
</p>
<h3 id="Labeled_statements">Labeled statements</h3> <h3 id="Labeled_statements">Labeled statements</h3>
...@@ -3479,12 +3510,12 @@ executes before the expression is evaluated. ...@@ -3479,12 +3510,12 @@ executes before the expression is evaluated.
</p> </p>
<pre> <pre>
if x := f(); x < y { if x := f(); x &lt; y {
return x; return x
} else if x > z { } else if x > z {
return z; return z
} else { } else {
return y; return y
} }
</pre> </pre>
...@@ -3530,7 +3561,7 @@ the expression <code>true</code>. ...@@ -3530,7 +3561,7 @@ the expression <code>true</code>.
<pre class="ebnf"> <pre class="ebnf">
ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" . ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
ExprCaseClause = ExprSwitchCase ":" [ StatementList ] . ExprCaseClause = ExprSwitchCase ":" { Statement ";" } .
ExprSwitchCase = "case" ExpressionList | "default" . ExprSwitchCase = "case" ExpressionList | "default" .
</pre> </pre>
...@@ -3555,15 +3586,15 @@ case 0, 1, 2, 3: s1() ...@@ -3555,15 +3586,15 @@ case 0, 1, 2, 3: s1()
case 4, 5, 6, 7: s2() case 4, 5, 6, 7: s2()
} }
switch x := f(); { // missing switch expression means "true" switch x := f() { // missing switch expression means "true"
case x &lt; 0: return -x case x &lt; 0: return -x
default: return x default: return x
} }
switch { switch {
case x &lt; y: f1(); case x &lt; y: f1()
case x &lt; z: f2(); case x &lt; z: f2()
case x == 4: f3(); case x == 4: f3()
} }
</pre> </pre>
...@@ -3581,7 +3612,7 @@ in the type assertion. ...@@ -3581,7 +3612,7 @@ in the type assertion.
<pre class="ebnf"> <pre class="ebnf">
TypeSwitchStmt = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" . TypeSwitchStmt = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
TypeSwitchGuard = [ identifier ":=" ] Expression "." "(" "type" ")" . TypeSwitchGuard = [ identifier ":=" ] Expression "." "(" "type" ")" .
TypeCaseClause = TypeSwitchCase ":" [ StatementList ] . TypeCaseClause = TypeSwitchCase ":" { Statement ";" } .
TypeSwitchCase = "case" TypeList | "default" . TypeSwitchCase = "case" TypeList | "default" .
TypeList = Type { "," Type } . TypeList = Type { "," Type } .
</pre> </pre>
...@@ -3610,17 +3641,17 @@ the following type switch: ...@@ -3610,17 +3641,17 @@ the following type switch:
<pre> <pre>
switch i := x.(type) { switch i := x.(type) {
case nil: case nil:
printString("x is nil"); printString("x is nil")
case int: case int:
printInt(i); // i is an int printInt(i) // i is an int
case float: case float:
printFloat(i); // i is a float printFloat(i) // i is a float
case func(int) float: case func(int) float:
printFunction(i); // i is a function printFunction(i) // i is a function
case bool, string: case bool, string:
printString("type is bool or string"); // i is an interface{} printString("type is bool or string") // i is an interface{}
default: default:
printString("don't know the type"); printString("don't know the type")
} }
</pre> </pre>
...@@ -3629,24 +3660,24 @@ could be rewritten: ...@@ -3629,24 +3660,24 @@ could be rewritten:
</p> </p>
<pre> <pre>
v := x; // x is evaluated exactly once v := x // x is evaluated exactly once
if v == nil { if v == nil {
printString("x is nil"); printString("x is nil")
} else if i, is_int := v.(int); is_int { } else if i, is_int := v.(int); is_int {
printInt(i); // i is an int printInt(i) // i is an int
} else if i, is_float := v.(float); is_float { } else if i, is_float := v.(float); is_float {
printFloat(i); // i is a float printFloat(i) // i is a float
} else if i, is_func := v.(func(int) float); is_func { } else if i, is_func := v.(func(int) float); is_func {
printFunction(i); // i is a function printFunction(i) // i is a function
} else { } else {
i1, is_bool := v.(bool); i1, is_bool := v.(bool)
i2, is_string := v.(string); i2, is_string := v.(string)
if is_bool || is_string { if is_bool || is_string {
i := v; i := v
printString("type is bool or string"); // i is an interface{} printString("type is bool or string") // i is an interface{}
} else { } else {
i := v; i := v
printString("don't know the type"); // i is an interface{} printString("don't know the type") // i is an interface{}
} }
} }
</pre> </pre>
...@@ -3694,13 +3725,13 @@ an increment or decrement statement. The init statement may be a ...@@ -3694,13 +3725,13 @@ an increment or decrement statement. The init statement may be a
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
ForClause = InitStmt ";" [ Condition ] ";" PostStmt . ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
InitStmt = SimpleStmt . InitStmt = SimpleStmt .
PostStmt = SimpleStmt . PostStmt = SimpleStmt .
</pre> </pre>
<pre> <pre>
for i := 0; i < 10; i++ { for i := 0; i &lt; 10; i++ {
f(i) f(i)
} }
</pre> </pre>
...@@ -3710,7 +3741,8 @@ If non-empty, the init statement is executed once before evaluating the ...@@ -3710,7 +3741,8 @@ If non-empty, the init statement is executed once before evaluating the
condition for the first iteration; condition for the first iteration;
the post statement is executed after each execution of the block (and the post statement is executed after each execution of the block (and
only if the block was executed). only if the block was executed).
Any element of the ForClause may be empty but the semicolons are Any element of the ForClause may be empty but the
<a href="#Semicolons">semicolons</a> are
required unless there is only a condition. required unless there is only a condition.
If the condition is absent, it is equivalent to <code>true</code>. If the condition is absent, it is equivalent to <code>true</code>.
</p> </p>
...@@ -3776,8 +3808,8 @@ after execution their values will be those of the last iteration. ...@@ -3776,8 +3808,8 @@ after execution their values will be those of the last iteration.
</p> </p>
<pre> <pre>
var a [10]string; var a [10]string
m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}; m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
for i, s := range a { for i, s := range a {
// type of i is int // type of i is int
...@@ -3786,8 +3818,8 @@ for i, s := range a { ...@@ -3786,8 +3818,8 @@ for i, s := range a {
g(i, s) g(i, s)
} }
var key string; var key string
var val interface {}; // value type of m is assignment compatible with val var val interface {} // value type of m is assignment compatible with val
for key, val = range m { for key, val = range m {
h(key, val) h(key, val)
} }
...@@ -3835,7 +3867,7 @@ cases all referring to communication operations. ...@@ -3835,7 +3867,7 @@ cases all referring to communication operations.
<pre class="ebnf"> <pre class="ebnf">
SelectStmt = "select" "{" { CommClause } "}" . SelectStmt = "select" "{" { CommClause } "}" .
CommClause = CommCase ":" StatementList . CommClause = CommCase ":" { Statement ";" } .
CommCase = "case" ( SendExpr | RecvExpr) | "default" . CommCase = "case" ( SendExpr | RecvExpr) | "default" .
SendExpr = Expression "&lt;-" Expression . SendExpr = Expression "&lt;-" Expression .
RecvExpr = [ Expression ( "=" | ":=" ) ] "&lt;-" Expression . RecvExpr = [ Expression ( "=" | ":=" ) ] "&lt;-" Expression .
...@@ -3870,15 +3902,15 @@ The receive case may declare a new variable using a ...@@ -3870,15 +3902,15 @@ The receive case may declare a new variable using a
</p> </p>
<pre> <pre>
var c, c1, c2 chan int; var c, c1, c2 chan int
var i1, i2 int; var i1, i2 int
select { select {
case i1 = &lt;-c1: case i1 = &lt;-c1:
print("received ", i1, " from c1\n"); print("received ", i1, " from c1\n")
case c2 &lt;- i2: case c2 &lt;- i2:
print("sent ", i2, " to c2\n"); print("sent ", i2, " to c2\n")
default: default:
print("no communication\n"); print("no communication\n")
} }
for { // send random sequence of bits to c for { // send random sequence of bits to c
...@@ -3952,9 +3984,9 @@ func complex_f2() (re float, im float) { ...@@ -3952,9 +3984,9 @@ func complex_f2() (re float, im float) {
The "return" statement returns the values of these variables. The "return" statement returns the values of these variables.
<pre> <pre>
func complex_f3() (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>
</li> </li>
...@@ -3978,7 +4010,7 @@ A "break" statement terminates execution of the innermost ...@@ -3978,7 +4010,7 @@ A "break" statement terminates execution of the innermost
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
BreakStmt = "break" [ Label ]. BreakStmt = "break" [ Label ] .
</pre> </pre>
<p> <p>
...@@ -3989,7 +4021,7 @@ terminates ...@@ -3989,7 +4021,7 @@ terminates
</p> </p>
<pre> <pre>
L: for i < n { L: for i &lt; n {
switch i { switch i {
case 5: break L case 5: break L
} }
...@@ -4004,7 +4036,7 @@ innermost "for" loop at its post statement (§<a href="#For_statements">For stat ...@@ -4004,7 +4036,7 @@ innermost "for" loop at its post statement (§<a href="#For_statements">For stat
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
ContinueStmt = "continue" [ Label ]. ContinueStmt = "continue" [ Label ] .
</pre> </pre>
<p> <p>
...@@ -4032,8 +4064,8 @@ instance, this example: ...@@ -4032,8 +4064,8 @@ instance, this example:
</p> </p>
<pre> <pre>
goto L; // BAD goto L // BAD
v := 3; v := 3
L: L:
</pre> </pre>
...@@ -4081,12 +4113,12 @@ but after the return values, if any, have been evaluated. ...@@ -4081,12 +4113,12 @@ but after the return values, if any, have been evaluated.
</p> </p>
<pre> <pre>
lock(l); lock(l)
defer unlock(l); // unlocking happens before surrounding function returns defer unlock(l) // unlocking happens before surrounding function returns
// prints 3 2 1 0 before surrounding function returns // prints 3 2 1 0 before surrounding function returns
for i := 0; i &lt;= 3; i++ { for i := 0; i &lt;= 3; i++ {
defer fmt.Print(i); defer fmt.Print(i)
} }
</pre> </pre>
...@@ -4218,10 +4250,10 @@ buffered channels: ...@@ -4218,10 +4250,10 @@ buffered channels:
</p> </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
s := make([]int, 10); // slice with len(s) == cap(s) == 10 s := make([]int, 10) // slice with len(s) == cap(s) == 10
c := make(chan int, 10); // channel with a buffer size of 10 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>
...@@ -4246,10 +4278,10 @@ Examples: ...@@ -4246,10 +4278,10 @@ Examples:
</p> </p>
<pre> <pre>
var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}; var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
var s = make([]int, 6); var s = make([]int, 6)
n1 := copy(s, &amp;a); // n1 == 6, s == []int{0, 1, 2, 3, 4, 5} n1 := copy(s, &amp;a) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
n2 := copy(s, s[2:]); // n2 == 4, s == []int{2, 3, 4, 5, 4, 5} n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
</pre> </pre>
...@@ -4293,7 +4325,7 @@ types, variables, and constants. ...@@ -4293,7 +4325,7 @@ types, variables, and constants.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
SourceFile = PackageClause { ImportDecl [ ";" ] } { TopLevelDecl [ ";" ] } . SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
</pre> </pre>
<h3 id="Package_clause">Package clause</h3> <h3 id="Package_clause">Package clause</h3>
...@@ -4333,10 +4365,9 @@ that specifies the package to be imported. ...@@ -4333,10 +4365,9 @@ that specifies the package to be imported.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
ImportDecl = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) . ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpecList = ImportSpec { ";" ImportSpec } [ ";" ] .
ImportSpec = [ "." | PackageName ] ImportPath . ImportSpec = [ "." | PackageName ] ImportPath .
ImportPath = StringLit . ImportPath = string_lit .
</pre> </pre>
<p> <p>
...@@ -4402,7 +4433,7 @@ import "fmt" ...@@ -4402,7 +4433,7 @@ import "fmt"
// Send the sequence 2, 3, 4, ... to channel 'ch'. // Send the sequence 2, 3, 4, ... to channel 'ch'.
func generate(ch chan&lt;- int) { func generate(ch chan&lt;- int) {
for i := 2; ; i++ { for i := 2; ; i++ {
ch &lt;- i; // Send 'i' to channel 'ch'. ch &lt;- i // Send 'i' to channel 'ch'.
} }
} }
...@@ -4411,26 +4442,26 @@ func generate(ch chan&lt;- int) { ...@@ -4411,26 +4442,26 @@ func generate(ch chan&lt;- int) {
func filter(src &lt;-chan int, dst chan&lt;- int, prime int) { func filter(src &lt;-chan int, dst chan&lt;- int, prime int) {
for i := range src { // Loop over values received from 'src'. for i := range src { // Loop over values received from 'src'.
if i%prime != 0 { if i%prime != 0 {
dst &lt;- i; // Send 'i' to channel 'dst'. dst &lt;- i // Send 'i' to channel 'dst'.
} }
} }
} }
// The prime sieve: Daisy-chain filter processes together. // The prime sieve: Daisy-chain filter processes together.
func sieve() { func sieve() {
ch := make(chan int); // Create a new channel. ch := make(chan int) // Create a new channel.
go generate(ch); // Start generate() as a subprocess. go generate(ch) // Start generate() as a subprocess.
for { for {
prime := &lt;-ch; prime := &lt;-ch
fmt.Print(prime, "\n"); fmt.Print(prime, "\n")
ch1 := make(chan int); ch1 := make(chan int)
go filter(ch, ch1, prime); go filter(ch, ch1, prime)
ch = ch1; ch = ch1
} }
} }
func main() { func main() {
sieve(); sieve()
} }
</pre> </pre>
...@@ -4453,8 +4484,8 @@ These two simple declarations are equivalent: ...@@ -4453,8 +4484,8 @@ These two simple declarations are equivalent:
</p> </p>
<pre> <pre>
var i int; var i int
var i int = 0; var i int = 0
</pre> </pre>
<p> <p>
...@@ -4462,8 +4493,8 @@ After ...@@ -4462,8 +4493,8 @@ After
</p> </p>
<pre> <pre>
type T struct { i int; f float; next *T }; type T struct { i int; f float; next *T }
t := new(T); t := new(T)
</pre> </pre>
<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