mirror of
https://github.com/golang/go
synced 2024-11-25 08:07:57 -07:00
doc/go1: most of the simple language changes
R=rsc, adg, r CC=golang-dev https://golang.org/cl/5477044
This commit is contained in:
parent
27cab90363
commit
136c04f71a
226
doc/go1.html
226
doc/go1.html
@ -31,17 +31,92 @@ r60 to compile and run under Go 1. Finally, it outlines the new
|
|||||||
<code>go</code> command for building Go programs and the new binary
|
<code>go</code> command for building Go programs and the new binary
|
||||||
release process being introduced. Most of these topics have more
|
release process being introduced. Most of these topics have more
|
||||||
thorough presentations elsewhere; such documents are linked below.
|
thorough presentations elsewhere; such documents are linked below.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="language">Changes to the language</h2>
|
<h2 id="language">Changes to the language</h2>
|
||||||
|
|
||||||
<h3 id="append">Append</h3>
|
<h3 id="append">Append</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <code>append</code> built-in function is variadic, so one can
|
||||||
|
append to a byte slice using the <code>...</code> syntax in the
|
||||||
|
call.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><!--{{code "progs/go1.go" `/greeting := ..byte/` `/append.*hello/`}}
|
||||||
|
--> greeting := []byte{}
|
||||||
|
greeting = append(greeting, []byte("hello ")...)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
By analogy with the similar property of <code>copy</code>, Go 1
|
||||||
|
permits a string to be appended (byte-wise) directly to a byte
|
||||||
|
slice; the conversion is no longer necessary:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><!--{{code "progs/go1.go" `/append.*world/`}}
|
||||||
|
--> greeting = append(greeting, "world"...)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is a new feature, so existing code needs no changes.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="close">Close</h3>
|
<h3 id="close">Close</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <code>close</code> built-in function lets a sender tell a receiver
|
||||||
|
that no more data will be transmitted on the channel. In Go 1 the
|
||||||
|
type system enforces the directionality when possible: it is illegal
|
||||||
|
to call <code>close</code> on a receive-only channel:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
var c chan int
|
||||||
|
var csend chan<- int = c
|
||||||
|
var crecv <-chan int = c
|
||||||
|
close(c) // legal
|
||||||
|
close(csend) // legal
|
||||||
|
close(crecv) // illegal
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
Existing code that attempts to close a receive-only channel was
|
||||||
|
erroneous even before Go 1 and should be fixed. The compiler will
|
||||||
|
now reject such code.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="literals">Composite literals</h3>
|
<h3 id="literals">Composite literals</h3>
|
||||||
|
|
||||||
<h3 id="init">Goroutines during init</h3>
|
<h3 id="init">Goroutines during init</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1 allows goroutines to be created and run during initialization.
|
||||||
|
(They used to be created but were not run until after initialization
|
||||||
|
completed.) Code that uses goroutines can now be called from
|
||||||
|
<code>init</code> routines and global initialization expressions
|
||||||
|
without introducing a deadlock.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><!--{{code "progs/go1.go" `/PackageGlobal/` `/^}/`}}
|
||||||
|
-->var PackageGlobal int
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
c := make(chan int)
|
||||||
|
go initializationFunction(c)
|
||||||
|
PackageGlobal = <-c
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is a new feature, so existing code needs no changes,
|
||||||
|
although it's possible that code that depends on goroutines not starting before <code>main</code> will break.
|
||||||
|
There was no such code in the standard repository.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="rune">The rune type</h3>
|
<h3 id="rune">The rune type</h3>
|
||||||
|
|
||||||
<h3 id="delete">Deleting from maps</h3>
|
<h3 id="delete">Deleting from maps</h3>
|
||||||
@ -77,14 +152,161 @@ the ignored value can be safely discarded from the program and
|
|||||||
will flag other uses of the syntax for inspection by the programmer.
|
will flag other uses of the syntax for inspection by the programmer.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="map_iteration">Iterating in maps</h3>
|
<h3 id="iteration">Iterating in maps</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In Go 1, the order in which elements are visited when iterating
|
||||||
|
over a map using a <code>for</code> <code>range</code> statement
|
||||||
|
is defined to be unpredictable, even if the same loop is run multiple
|
||||||
|
times with the same map.
|
||||||
|
Code should not assume that the elements are visited in any particular order.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><!--{{code "progs/go1.go" `/Sunday/` `/^ }/`}}
|
||||||
|
--> m := map[string]int{"Sunday": 0, "Monday": 1}
|
||||||
|
for name, value := range m {
|
||||||
|
// This loop should not assume Sunday will be visited first.
|
||||||
|
f(name, value)
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is one change where tools cannot help. Most existing code
|
||||||
|
will be unaffected, but some programs may break or misbehave; we
|
||||||
|
recommend manual checking of all range statements over maps to
|
||||||
|
verify they do not depend on iteration order. There were a few such
|
||||||
|
examples in the standard repository; they have been fixed.
|
||||||
|
Note that it was already incorrect to depend on the iteration order, which
|
||||||
|
was unspecified. This change codifies the unpredictability.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="multiple_assignment">Multiple assignment</h3>
|
<h3 id="multiple_assignment">Multiple assignment</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1 fully specifies the evaluation order in multiple assignment
|
||||||
|
statements. In particular, if the left-hand side of the assignment
|
||||||
|
statement contains expressions that require evaluation, such as
|
||||||
|
function calls or array indexing operations, these will all be done
|
||||||
|
using the usual left-to-right rule before any variables are assigned
|
||||||
|
their value. Once everything is evaluated, the actual assignments
|
||||||
|
proceed in left-to-right order.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
These examples illustrate the behavior.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><!--{{code "progs/go1.go" `/sa :=/` `/then sc.0. = 2/`}}
|
||||||
|
--> sa := []int{1, 2, 3}
|
||||||
|
i := 0
|
||||||
|
i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2
|
||||||
|
|
||||||
|
sb := []int{1, 2, 3}
|
||||||
|
j := 0
|
||||||
|
sb[j], j = 2, 1 // sets sb[0] = 2, j = 1
|
||||||
|
|
||||||
|
sc := []int{1, 2, 3}
|
||||||
|
sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is one change where tools cannot help, but breakage is unlikely.
|
||||||
|
No code in the standard repository was broken by this change, and code
|
||||||
|
that depended on the previous unspecified behavior was already incorrect.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="shadowing">Returns and shadowed variables</h3>
|
<h3 id="shadowing">Returns and shadowed variables</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A shadowed variable is one that has the same name as another variable in an inner scope.
|
||||||
|
In functions with named return values,
|
||||||
|
the Go 1 compilers disallow return statements without arguments if any of the named return values is shadowed at the point of the return statement.
|
||||||
|
(It isn't part of the specification, because this is one area we are still exploring;
|
||||||
|
the situation is analogous to the compilers rejecting functions that do not end with an explicit return statement.)
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This function implicitly returns a shadowed return value and will be rejected by the compiler:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func Bug() (i, j, k int) {
|
||||||
|
for i = 0; i < 5; i++ {
|
||||||
|
for j := 0; j < 5; j++ { // Redeclares j.
|
||||||
|
k += i*j
|
||||||
|
if k > 100 {
|
||||||
|
return // Rejected: j is shadowed here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return // OK: j is not shadowed here.
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
Code that shadows return values in this way will be rejected by the compiler and will need to be fixed by hand.
|
||||||
|
The few cases that arose in the standard repository were mostly bugs.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="unexported">Copying structs with unexported fields</h3>
|
||||||
|
|
||||||
<h3 id="equality">Equality of structs and arrays</h3>
|
<h3 id="equality">Equality of structs and arrays</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1 defines equality and inequality (<code>==</code> and
|
||||||
|
<code>!=</code>) for struct and array values, respectively, provided
|
||||||
|
the elements of the data structures can themselves be compared.
|
||||||
|
That is, if equality is defined for all the fields of a struct (or
|
||||||
|
an array element), then it is defined for the struct (or array).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
As a result, structs and arrays can now be used as map keys:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><!--{{code "progs/go1.go" `/type Day struct/` `/Printf/`}}
|
||||||
|
--> // type Day struct {
|
||||||
|
// long string
|
||||||
|
// short string
|
||||||
|
// }
|
||||||
|
// Christmas := Day{"Christmas", "XMas"}
|
||||||
|
// Thanksgiving := Day{"Thanksgiving", "Turkey"}
|
||||||
|
// holiday := map[Day]bool {
|
||||||
|
// Christmas: true,
|
||||||
|
// Thanksgiving: true,
|
||||||
|
// }
|
||||||
|
// fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note that equality is still undefined for slices, for which the
|
||||||
|
calculation is in general infeasible. Also note that the ordered
|
||||||
|
comparison operators (<code><</code> <code><=</code>
|
||||||
|
<code>></code> <code>>=</code>) are still undefined for
|
||||||
|
structs and arrays.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is a new feature, so existing code needs no changes.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="funcs">Function and map equality</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1 disallows checking for equality of functions and maps,
|
||||||
|
respectively, except to compare them directly to <code>nil</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
Existing code that depends on function or map equality will be
|
||||||
|
rejected by the compiler and will need to be fixed by hand.
|
||||||
|
Few programs will be affected, but the fix may require some
|
||||||
|
redesign.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="library">Changes to the library</h2>
|
<h2 id="library">Changes to the library</h2>
|
||||||
|
|
||||||
<h3 id="hierarchy">The package hierarchy</h3>
|
<h3 id="hierarchy">The package hierarchy</h3>
|
||||||
@ -106,7 +328,7 @@ while <a href="#deleted">others</a> have been deleted outright.
|
|||||||
<th align="left">Old path</th>
|
<th align="left">Old path</th>
|
||||||
<th align="left">New path</th>
|
<th align="left">New path</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>asn1 <td>encoding/asn1
|
<tr><td>asn1</td> <td>encoding/asn1</td></tr>
|
||||||
<tr><td>csv</td> <td>encoding/csv</td></tr>
|
<tr><td>csv</td> <td>encoding/csv</td></tr>
|
||||||
<tr><td>gob</td> <td>encoding/gob</td></tr>
|
<tr><td>gob</td> <td>encoding/gob</td></tr>
|
||||||
<tr><td>json</td> <td>encoding/json</td></tr>
|
<tr><td>json</td> <td>encoding/json</td></tr>
|
||||||
|
182
doc/go1.tmpl
182
doc/go1.tmpl
@ -27,17 +27,79 @@ r60 to compile and run under Go 1. Finally, it outlines the new
|
|||||||
<code>go</code> command for building Go programs and the new binary
|
<code>go</code> command for building Go programs and the new binary
|
||||||
release process being introduced. Most of these topics have more
|
release process being introduced. Most of these topics have more
|
||||||
thorough presentations elsewhere; such documents are linked below.
|
thorough presentations elsewhere; such documents are linked below.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="language">Changes to the language</h2>
|
<h2 id="language">Changes to the language</h2>
|
||||||
|
|
||||||
<h3 id="append">Append</h3>
|
<h3 id="append">Append</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <code>append</code> built-in function is variadic, so one can
|
||||||
|
append to a byte slice using the <code>...</code> syntax in the
|
||||||
|
call.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{code "progs/go1.go" `/greeting := ..byte/` `/append.*hello/`}}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
By analogy with the similar property of <code>copy</code>, Go 1
|
||||||
|
permits a string to be appended (byte-wise) directly to a byte
|
||||||
|
slice; the conversion is no longer necessary:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{code "progs/go1.go" `/append.*world/`}}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is a new feature, so existing code needs no changes.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="close">Close</h3>
|
<h3 id="close">Close</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <code>close</code> built-in function lets a sender tell a receiver
|
||||||
|
that no more data will be transmitted on the channel. In Go 1 the
|
||||||
|
type system enforces the directionality when possible: it is illegal
|
||||||
|
to call <code>close</code> on a receive-only channel:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
var c chan int
|
||||||
|
var csend chan<- int = c
|
||||||
|
var crecv <-chan int = c
|
||||||
|
close(c) // legal
|
||||||
|
close(csend) // legal
|
||||||
|
close(crecv) // illegal
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
Existing code that attempts to close a receive-only channel was
|
||||||
|
erroneous even before Go 1 and should be fixed. The compiler will
|
||||||
|
now reject such code.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="literals">Composite literals</h3>
|
<h3 id="literals">Composite literals</h3>
|
||||||
|
|
||||||
<h3 id="init">Goroutines during init</h3>
|
<h3 id="init">Goroutines during init</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1 allows goroutines to be created and run during initialization.
|
||||||
|
(They used to be created but were not run until after initialization
|
||||||
|
completed.) Code that uses goroutines can now be called from
|
||||||
|
<code>init</code> routines and global initialization expressions
|
||||||
|
without introducing a deadlock.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{code "progs/go1.go" `/PackageGlobal/` `/^}/`}}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is a new feature, so existing code needs no changes,
|
||||||
|
although it's possible that code that depends on goroutines not starting before <code>main</code> will break.
|
||||||
|
There was no such code in the standard repository.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="rune">The rune type</h3>
|
<h3 id="rune">The rune type</h3>
|
||||||
|
|
||||||
<h3 id="delete">Deleting from maps</h3>
|
<h3 id="delete">Deleting from maps</h3>
|
||||||
@ -71,14 +133,132 @@ the ignored value can be safely discarded from the program and
|
|||||||
will flag other uses of the syntax for inspection by the programmer.
|
will flag other uses of the syntax for inspection by the programmer.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="map_iteration">Iterating in maps</h3>
|
<h3 id="iteration">Iterating in maps</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In Go 1, the order in which elements are visited when iterating
|
||||||
|
over a map using a <code>for</code> <code>range</code> statement
|
||||||
|
is defined to be unpredictable, even if the same loop is run multiple
|
||||||
|
times with the same map.
|
||||||
|
Code should not assume that the elements are visited in any particular order.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{code "progs/go1.go" `/Sunday/` `/^ }/`}}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is one change where tools cannot help. Most existing code
|
||||||
|
will be unaffected, but some programs may break or misbehave; we
|
||||||
|
recommend manual checking of all range statements over maps to
|
||||||
|
verify they do not depend on iteration order. There were a few such
|
||||||
|
examples in the standard repository; they have been fixed.
|
||||||
|
Note that it was already incorrect to depend on the iteration order, which
|
||||||
|
was unspecified. This change codifies the unpredictability.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="multiple_assignment">Multiple assignment</h3>
|
<h3 id="multiple_assignment">Multiple assignment</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1 fully specifies the evaluation order in multiple assignment
|
||||||
|
statements. In particular, if the left-hand side of the assignment
|
||||||
|
statement contains expressions that require evaluation, such as
|
||||||
|
function calls or array indexing operations, these will all be done
|
||||||
|
using the usual left-to-right rule before any variables are assigned
|
||||||
|
their value. Once everything is evaluated, the actual assignments
|
||||||
|
proceed in left-to-right order.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
These examples illustrate the behavior.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{code "progs/go1.go" `/sa :=/` `/then sc.0. = 2/`}}
|
||||||
|
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is one change where tools cannot help, but breakage is unlikely.
|
||||||
|
No code in the standard repository was broken by this change, and code
|
||||||
|
that depended on the previous unspecified behavior was already incorrect.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h3 id="shadowing">Returns and shadowed variables</h3>
|
<h3 id="shadowing">Returns and shadowed variables</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A shadowed variable is one that has the same name as another variable in an inner scope.
|
||||||
|
In functions with named return values,
|
||||||
|
the Go 1 compilers disallow return statements without arguments if any of the named return values is shadowed at the point of the return statement.
|
||||||
|
(It isn't part of the specification, because this is one area we are still exploring;
|
||||||
|
the situation is analogous to the compilers rejecting functions that do not end with an explicit return statement.)
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This function implicitly returns a shadowed return value and will be rejected by the compiler:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func Bug() (i, j, k int) {
|
||||||
|
for i = 0; i < 5; i++ {
|
||||||
|
for j := 0; j < 5; j++ { // Redeclares j.
|
||||||
|
k += i*j
|
||||||
|
if k > 100 {
|
||||||
|
return // Rejected: j is shadowed here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return // OK: j is not shadowed here.
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
Code that shadows return values in this way will be rejected by the compiler and will need to be fixed by hand.
|
||||||
|
The few cases that arose in the standard repository were mostly bugs.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="unexported">Copying structs with unexported fields</h3>
|
||||||
|
|
||||||
<h3 id="equality">Equality of structs and arrays</h3>
|
<h3 id="equality">Equality of structs and arrays</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1 defines equality and inequality (<code>==</code> and
|
||||||
|
<code>!=</code>) for struct and array values, respectively, provided
|
||||||
|
the elements of the data structures can themselves be compared.
|
||||||
|
That is, if equality is defined for all the fields of a struct (or
|
||||||
|
an array element), then it is defined for the struct (or array).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
As a result, structs and arrays can now be used as map keys:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{code "progs/go1.go" `/type Day struct/` `/Printf/`}}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Note that equality is still undefined for slices, for which the
|
||||||
|
calculation is in general infeasible. Also note that the ordered
|
||||||
|
comparison operators (<code><</code> <code><=</code>
|
||||||
|
<code>></code> <code>>=</code>) are still undefined for
|
||||||
|
structs and arrays.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
This is a new feature, so existing code needs no changes.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="funcs">Function and map equality</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1 disallows checking for equality of functions and maps,
|
||||||
|
respectively, except to compare them directly to <code>nil</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>Updating</em>:
|
||||||
|
Existing code that depends on function or map equality will be
|
||||||
|
rejected by the compiler and will need to be fixed by hand.
|
||||||
|
Few programs will be affected, but the fix may require some
|
||||||
|
redesign.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="library">Changes to the library</h2>
|
<h2 id="library">Changes to the library</h2>
|
||||||
|
|
||||||
<h3 id="hierarchy">The package hierarchy</h3>
|
<h3 id="hierarchy">The package hierarchy</h3>
|
||||||
|
@ -9,7 +9,11 @@ package main
|
|||||||
import "log"
|
import "log"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
stringAppend()
|
||||||
mapDelete()
|
mapDelete()
|
||||||
|
mapIteration()
|
||||||
|
multipleAssignment()
|
||||||
|
structEquality()
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapDelete() {
|
func mapDelete() {
|
||||||
@ -20,3 +24,73 @@ func mapDelete() {
|
|||||||
log.Fatal("mapDelete:", m)
|
log.Fatal("mapDelete:", m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stringAppend() {
|
||||||
|
greeting := []byte{}
|
||||||
|
greeting = append(greeting, []byte("hello ")...)
|
||||||
|
greeting = append(greeting, "world"...)
|
||||||
|
if string(greeting) != "hello world" {
|
||||||
|
log.Fatal("stringAppend: ", string(greeting))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapIteration() {
|
||||||
|
m := map[string]int{"Sunday": 0, "Monday": 1}
|
||||||
|
for name, value := range m {
|
||||||
|
// This loop should not assume Sunday will be visited first.
|
||||||
|
f(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func assert(t bool) {
|
||||||
|
if !t {
|
||||||
|
log.Panic("assertion fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func multipleAssignment() {
|
||||||
|
sa := []int{1, 2, 3}
|
||||||
|
i := 0
|
||||||
|
i, sa[i] = 1, 2 // sets i = 1, sa[0] = 2
|
||||||
|
|
||||||
|
sb := []int{1, 2, 3}
|
||||||
|
j := 0
|
||||||
|
sb[j], j = 2, 1 // sets sb[0] = 2, j = 1
|
||||||
|
|
||||||
|
sc := []int{1, 2, 3}
|
||||||
|
sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)
|
||||||
|
|
||||||
|
assert(i == 1 && sa[0] == 2)
|
||||||
|
assert(j == 1 && sb[0] == 2)
|
||||||
|
assert(sc[0] == 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func structEquality() {
|
||||||
|
// Feature not net in repo.
|
||||||
|
// type Day struct {
|
||||||
|
// long string
|
||||||
|
// short string
|
||||||
|
// }
|
||||||
|
// Christmas := Day{"Christmas", "XMas"}
|
||||||
|
// Thanksgiving := Day{"Thanksgiving", "Turkey"}
|
||||||
|
// holiday := map[Day]bool {
|
||||||
|
// Christmas: true,
|
||||||
|
// Thanksgiving: true,
|
||||||
|
// }
|
||||||
|
// fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
|
||||||
|
}
|
||||||
|
|
||||||
|
func f(string, int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func initializationFunction(c chan int) {
|
||||||
|
c <- 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var PackageGlobal int
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
c := make(chan int)
|
||||||
|
go initializationFunction(c)
|
||||||
|
PackageGlobal = <-c
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user