1
0
mirror of https://github.com/golang/go synced 2024-11-25 00:07:56 -07:00

doc/go1: the rest of the language changes

R=rsc
CC=golang-dev
https://golang.org/cl/5478047
This commit is contained in:
Rob Pike 2011-12-09 08:31:57 -08:00
parent 940c25faa4
commit 2e338fa69f
3 changed files with 316 additions and 3 deletions

View File

@ -90,6 +90,51 @@ now reject such code.
<h3 id="literals">Composite literals</h3>
<p>
In Go 1, a composite literal of array, slice, or map type can elide the
type specification for the elements' initializers if they are of pointer type.
All four of the initializations in this example are legal; the last one was illegal before Go 1.
</p>
<pre><!--{{code "progs/go1.go" `/type Date struct/` `/STOP/`}}
--> type Date struct {
month string
day int
}
// Struct values, fully qualified; always legal.
holiday1 := []Date{
Date{&#34;Feb&#34;, 14},
Date{&#34;Nov&#34;, 11},
Date{&#34;Dec&#34;, 25},
}
// Struct values, type name elided; always legal.
holiday2 := []Date{
{&#34;Feb&#34;, 14},
{&#34;Nov&#34;, 11},
{&#34;Dec&#34;, 25},
}
// Pointers, fully qualified, always legal.
holiday3 := []*Date{
&amp;Date{&#34;Feb&#34;, 14},
&amp;Date{&#34;Nov&#34;, 11},
&amp;Date{&#34;Dec&#34;, 25},
}
// Pointers, type name elided; legal in Go 1.
holiday4 := []*Date{
{&#34;Feb&#34;, 14},
{&#34;Nov&#34;, 11},
{&#34;Dec&#34;, 25},
}
</pre>
<p>
<em>Updating</em>:
This change has no effect on existing code, but the command
<code>gofmt</code> <code>-s</code> applied to existing source
will, among other things, elide explicit element types wherever permitted.
</p>
<h3 id="init">Goroutines during init</h3>
<p>
@ -119,6 +164,62 @@ There was no such code in the standard repository.
<h3 id="rune">The rune type</h3>
<p>
Go 1 introduces a new basic type, <code>rune</code>, to be used to represent
individual Unicode code points.
It is an alias for <code>int32</code>, analogous to <code>byte</code>
as an alias for <code>uint8</code>.
</p>
<p>
Character literals such as <code>'a'</code>, <code>'語'</code>, and <code>'\u0345'</code>
now have default type <code>rune</code>,
analogous to <code>1.0</code> having default type <code>float64</code>.
A variable initialized to a character constant will therefore
have type <code>rune</code> unless otherwise specified.
</p>
<p>
Libraries have been updated to use <code>rune</code> rather than <code>int</code>
when appropriate. For instance, the functions <code>unicode.ToLower</code> and
relatives now take and return a <code>rune</code>.
</p>
<pre><!--{{code "progs/go1.go" `/STARTRUNE/` `/ENDRUNE/`}}
--> delta := &#39;δ&#39; // delta has type rune.
var DELTA rune
DELTA = unicode.ToUpper(delta)
epsilon := unicode.ToLower(DELTA + 1)
if epsilon != &#39;δ&#39;+1 {
log.Fatal(&#34;inconsistent casing for Greek&#34;)
}
</pre>
<p>
<em>Updating</em>:
Most source code will be unaffected by this because the type inference from
<code>:=</code> initializers introduces the new type silently, and it propagates
from there.
Some code may get type errors that a trivial conversion will resolve.
</p>
<h3 id="error">The error type</h3>
<p>
Go 1 introduces a new built-in type, <code>error</code>, which has the following definition:
</p>
<pre>
type error interface {
Error() string
}
</pre>
<p>
Since the consequences of this type are all in the package library,
it is discussed <a href="errors">below</a>.
</p>
<h3 id="delete">Deleting from maps</h3>
<p>
@ -126,7 +227,7 @@ The original syntax for deleting an element in a map was:
</p>
<pre>
m[x] = ignored, false
m[k] = ignored, false
</pre>
<p>
@ -210,6 +311,7 @@ These examples illustrate the behavior.
sc[0], sc[0] = 1, 2 // sets sc[0] = 1, then sc[0] = 2 (so sc[0] = 2 at end)
</pre>
<p>
<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
@ -252,6 +354,54 @@ The few cases that arose in the standard repository were mostly bugs.
<h3 id="unexported">Copying structs with unexported fields</h3>
<p>
Go 1 relaxes the rules about accessing structs with unexported (lower-case) fields,
permitting a client package to assign (and therefore copy) such a struct.
Of course, the client package still cannot access such fields individually.
</p>
<p>
As an example, if package <code>p</code> includes the definitions,
</p>
<pre>
type Struct struct {
Public int
secret int
}
func NewStruct(a int) Struct { // Note: not a pointer.
return Struct{a, f(a)}
}
func (s Struct) String() string {
return fmt.Sprintf("{%d (secret %d)}", s.Public, s.secret)
}
</pre>
<p>
a package that imports <code>p</code> can assign and copy values of type
<code>p.Struct</code> at will.
Behind the scenes the unexported fields will be assigned and copied just
as if they were exported,
but the client code will never be aware of them. The code
</p>
<pre>
import "p"
myStruct := p.NewStruct(23)
copyOfMyStruct := myStruct
fmt.Println(myStruct, copyOfMyStruct)
</pre>
<p>
will show that the secret field of the struct has been copied to the new value.
</p>
<p>
<em>Updating</em>:
This is a new feature, so existing code needs no changes.
</p>
<h3 id="equality">Equality of structs and arrays</h3>
<p>

View File

@ -81,6 +81,22 @@ now reject such code.
<h3 id="literals">Composite literals</h3>
<p>
In Go 1, a composite literal of array, slice, or map type can elide the
type specification for the elements' initializers if they are of pointer type.
All four of the initializations in this example are legal; the last one was illegal before Go 1.
</p>
{{code "progs/go1.go" `/type Date struct/` `/STOP/`}}
<p>
<em>Updating</em>:
This change has no effect on existing code, but the command
<code>gofmt</code> <code>-s</code> applied to existing source
will, among other things, elide explicit element types wherever permitted.
</p>
<h3 id="init">Goroutines during init</h3>
<p>
@ -102,6 +118,54 @@ There was no such code in the standard repository.
<h3 id="rune">The rune type</h3>
<p>
Go 1 introduces a new basic type, <code>rune</code>, to be used to represent
individual Unicode code points.
It is an alias for <code>int32</code>, analogous to <code>byte</code>
as an alias for <code>uint8</code>.
</p>
<p>
Character literals such as <code>'a'</code>, <code>'語'</code>, and <code>'\u0345'</code>
now have default type <code>rune</code>,
analogous to <code>1.0</code> having default type <code>float64</code>.
A variable initialized to a character constant will therefore
have type <code>rune</code> unless otherwise specified.
</p>
<p>
Libraries have been updated to use <code>rune</code> rather than <code>int</code>
when appropriate. For instance, the functions <code>unicode.ToLower</code> and
relatives now take and return a <code>rune</code>.
</p>
{{code "progs/go1.go" `/STARTRUNE/` `/ENDRUNE/`}}
<p>
<em>Updating</em>:
Most source code will be unaffected by this because the type inference from
<code>:=</code> initializers introduces the new type silently, and it propagates
from there.
Some code may get type errors that a trivial conversion will resolve.
</p>
<h3 id="error">The error type</h3>
<p>
Go 1 introduces a new built-in type, <code>error</code>, which has the following definition:
</p>
<pre>
type error interface {
Error() string
}
</pre>
<p>
Since the consequences of this type are all in the package library,
it is discussed <a href="errors">below</a>.
</p>
<h3 id="delete">Deleting from maps</h3>
<p>
@ -109,7 +173,7 @@ The original syntax for deleting an element in a map was:
</p>
<pre>
m[x] = ignored, false
m[k] = ignored, false
</pre>
<p>
@ -174,6 +238,7 @@ These examples illustrate the behavior.
{{code "progs/go1.go" `/sa :=/` `/then sc.0. = 2/`}}
<p>
<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
@ -216,6 +281,54 @@ The few cases that arose in the standard repository were mostly bugs.
<h3 id="unexported">Copying structs with unexported fields</h3>
<p>
Go 1 relaxes the rules about accessing structs with unexported (lower-case) fields,
permitting a client package to assign (and therefore copy) such a struct.
Of course, the client package still cannot access such fields individually.
</p>
<p>
As an example, if package <code>p</code> includes the definitions,
</p>
<pre>
type Struct struct {
Public int
secret int
}
func NewStruct(a int) Struct { // Note: not a pointer.
return Struct{a, f(a)}
}
func (s Struct) String() string {
return fmt.Sprintf("{%d (secret %d)}", s.Public, s.secret)
}
</pre>
<p>
a package that imports <code>p</code> can assign and copy values of type
<code>p.Struct</code> at will.
Behind the scenes the unexported fields will be assigned and copied just
as if they were exported,
but the client code will never be aware of them. The code
</p>
<pre>
import "p"
myStruct := p.NewStruct(23)
copyOfMyStruct := myStruct
fmt.Println(myStruct, copyOfMyStruct)
</pre>
<p>
will show that the secret field of the struct has been copied to the new value.
</p>
<p>
<em>Updating</em>:
This is a new feature, so existing code needs no changes.
</p>
<h3 id="equality">Equality of structs and arrays</h3>
<p>

View File

@ -6,7 +6,10 @@
package main
import "log"
import (
"log"
"unicode"
)
func main() {
stringAppend()
@ -14,6 +17,8 @@ func main() {
mapIteration()
multipleAssignment()
structEquality()
compositeLiterals()
runeType()
}
func mapDelete() {
@ -80,6 +85,51 @@ func structEquality() {
// fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
}
func compositeLiterals() {
type Date struct {
month string
day int
}
// Struct values, fully qualified; always legal.
holiday1 := []Date{
Date{"Feb", 14},
Date{"Nov", 11},
Date{"Dec", 25},
}
// Struct values, type name elided; always legal.
holiday2 := []Date{
{"Feb", 14},
{"Nov", 11},
{"Dec", 25},
}
// Pointers, fully qualified, always legal.
holiday3 := []*Date{
&Date{"Feb", 14},
&Date{"Nov", 11},
&Date{"Dec", 25},
}
// Pointers, type name elided; legal in Go 1.
holiday4 := []*Date{
{"Feb", 14},
{"Nov", 11},
{"Dec", 25},
}
// STOP OMIT
_, _, _, _ = holiday1, holiday2, holiday3, holiday4
}
func runeType() {
// STARTRUNE OMIT
delta := 'δ' // delta has type rune.
var DELTA rune
DELTA = unicode.ToUpper(delta)
epsilon := unicode.ToLower(DELTA + 1)
if epsilon != 'δ'+1 {
log.Fatal("inconsistent casing for Greek")
}
// ENDRUNE OMIT
}
func f(string, int) {
}