mirror of
https://github.com/golang/go
synced 2024-11-24 17:00:01 -07:00
go_tutorial: removed outdated use of semicolons
R=r CC=golang-dev https://golang.org/cl/1013042
This commit is contained in:
parent
69a2e1dc52
commit
a82349614b
@ -184,7 +184,7 @@ string variable we will use to build the output.
|
|||||||
The declaration statement has the form
|
The declaration statement has the form
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
var s string = "";
|
var s string = ""
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
This is the <code>var</code> keyword, followed by the name of the variable, followed by
|
This is the <code>var</code> keyword, followed by the name of the variable, followed by
|
||||||
@ -195,13 +195,13 @@ string constant is of type string, we don't have to tell the compiler that.
|
|||||||
We could write
|
We could write
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
var s = "";
|
var s = ""
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
or we could go even shorter and write the idiom
|
or we could go even shorter and write the idiom
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
s := "";
|
s := ""
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
The <code>:=</code> operator is used a lot in Go to represent an initializing declaration.
|
The <code>:=</code> operator is used a lot in Go to represent an initializing declaration.
|
||||||
@ -264,8 +264,8 @@ However the following statements are illegal because they would modify
|
|||||||
a <code>string</code> value:
|
a <code>string</code> value:
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
s[0] = 'x';
|
s[0] = 'x'
|
||||||
(*p)[1] = 'y';
|
(*p)[1] = 'y'
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
In C++ terms, Go strings are a bit like <code>const strings</code>, while pointers
|
In C++ terms, Go strings are a bit like <code>const strings</code>, while pointers
|
||||||
@ -277,7 +277,7 @@ read on.
|
|||||||
Arrays are declared like this:
|
Arrays are declared like this:
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
var arrayOfInt [10]int;
|
var arrayOfInt [10]int
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
Arrays, like strings, are values, but they are mutable. This differs
|
Arrays, like strings, are values, but they are mutable. This differs
|
||||||
@ -341,7 +341,7 @@ If you are creating a regular array but want the compiler to count the
|
|||||||
elements for you, use <code>...</code> as the array size:
|
elements for you, use <code>...</code> as the array size:
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
s := sum(&[...]int{1,2,3});
|
s := sum(&[...]int{1,2,3})
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
In practice, though, unless you're meticulous about storage layout within a
|
In practice, though, unless you're meticulous about storage layout within a
|
||||||
@ -349,7 +349,7 @@ data structure, a slice itself—using empty brackets and no
|
|||||||
<code>&</code>—is all you need:
|
<code>&</code>—is all you need:
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
s := sum([]int{1,2,3});
|
s := sum([]int{1,2,3})
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
There are also maps, which you can initialize like this:
|
There are also maps, which you can initialize like this:
|
||||||
@ -391,13 +391,13 @@ returns a pointer to the allocated storage.
|
|||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
type T struct { a, b int }
|
type T struct { a, b int }
|
||||||
var t *T = new(T);
|
var t *T = new(T)
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
or the more idiomatic
|
or the more idiomatic
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
t := new(T);
|
t := new(T)
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
Some types—maps, slices, and channels (see below)—have reference semantics.
|
Some types—maps, slices, and channels (see below)—have reference semantics.
|
||||||
@ -406,14 +406,14 @@ referencing the same underlying data will see the modification. For these three
|
|||||||
types you want to use the built-in function <code>make()</code>:
|
types you want to use the built-in function <code>make()</code>:
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
m := make(map[string]int);
|
m := make(map[string]int)
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
This statement initializes a new map ready to store entries.
|
This statement initializes a new map ready to store entries.
|
||||||
If you just declare the map, as in
|
If you just declare the map, as in
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
var m map[string]int;
|
var m map[string]int
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
it creates a <code>nil</code> reference that cannot hold anything. To use the map,
|
it creates a <code>nil</code> reference that cannot hold anything. To use the map,
|
||||||
@ -518,9 +518,9 @@ the ones used to build maps and arrays, to construct a new heap-allocated
|
|||||||
object. We could write
|
object. We could write
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
n := new(File);
|
n := new(File)
|
||||||
n.fd = fd;
|
n.fd = fd
|
||||||
n.name = name;
|
n.name = name
|
||||||
return n
|
return n
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
@ -640,7 +640,7 @@ We can now use our new package:
|
|||||||
11 )
|
11 )
|
||||||
<p>
|
<p>
|
||||||
13 func main() {
|
13 func main() {
|
||||||
14 hello := []byte{'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n'}
|
14 hello := []byte("hello, world\n")
|
||||||
15 file.Stdout.Write(hello)
|
15 file.Stdout.Write(hello)
|
||||||
16 file, err := file.Open("/does/not/exist", 0, 0)
|
16 file, err := file.Open("/does/not/exist", 0, 0)
|
||||||
17 if file == nil {
|
17 if file == nil {
|
||||||
@ -903,7 +903,7 @@ to test that the result is sorted.
|
|||||||
14 a := sort.IntArray(data)
|
14 a := sort.IntArray(data)
|
||||||
15 sort.Sort(a)
|
15 sort.Sort(a)
|
||||||
16 if !sort.IsSorted(a) {
|
16 if !sort.IsSorted(a) {
|
||||||
17 panic()
|
17 panic("fail")
|
||||||
18 }
|
18 }
|
||||||
19 }
|
19 }
|
||||||
</pre>
|
</pre>
|
||||||
@ -1050,7 +1050,7 @@ Schematically, given a value <code>v</code>, it does this:
|
|||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
s, ok := v.(Stringer); // Test whether v implements "String()"
|
s, ok := v.(Stringer) // Test whether v implements "String()"
|
||||||
if ok {
|
if ok {
|
||||||
result = s.String()
|
result = s.String()
|
||||||
} else {
|
} else {
|
||||||
@ -1077,7 +1077,7 @@ interface type defined in the <code>io</code> library:
|
|||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
type Writer interface {
|
type Writer interface {
|
||||||
Write(p []byte) (n int, err os.Error);
|
Write(p []byte) (n int, err os.Error)
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
@ -1162,17 +1162,17 @@ this starts the function running in parallel with the current
|
|||||||
computation but in the same address space:
|
computation but in the same address space:
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
go sum(hugeArray); // calculate sum in the background
|
go sum(hugeArray) // calculate sum in the background
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
If you want to know when the calculation is done, pass a channel
|
If you want to know when the calculation is done, pass a channel
|
||||||
on which it can report back:
|
on which it can report back:
|
||||||
<p>
|
<p>
|
||||||
<pre>
|
<pre>
|
||||||
ch := make(chan int);
|
ch := make(chan int)
|
||||||
go sum(hugeArray, ch);
|
go sum(hugeArray, ch)
|
||||||
// ... do something else for a while
|
// ... do something else for a while
|
||||||
result := <-ch; // wait for, and retrieve, result
|
result := <-ch // wait for, and retrieve, result
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
Back to our prime sieve. Here's how the sieve pipeline is stitched
|
Back to our prime sieve. Here's how the sieve pipeline is stitched
|
||||||
|
@ -143,7 +143,7 @@ string variable we will use to build the output.
|
|||||||
|
|
||||||
The declaration statement has the form
|
The declaration statement has the form
|
||||||
|
|
||||||
var s string = "";
|
var s string = ""
|
||||||
|
|
||||||
This is the "var" keyword, followed by the name of the variable, followed by
|
This is the "var" keyword, followed by the name of the variable, followed by
|
||||||
its type, followed by an equals sign and an initial value for the variable.
|
its type, followed by an equals sign and an initial value for the variable.
|
||||||
@ -152,11 +152,11 @@ Go tries to be terse, and this declaration could be shortened. Since the
|
|||||||
string constant is of type string, we don't have to tell the compiler that.
|
string constant is of type string, we don't have to tell the compiler that.
|
||||||
We could write
|
We could write
|
||||||
|
|
||||||
var s = "";
|
var s = ""
|
||||||
|
|
||||||
or we could go even shorter and write the idiom
|
or we could go even shorter and write the idiom
|
||||||
|
|
||||||
s := "";
|
s := ""
|
||||||
|
|
||||||
The ":=" operator is used a lot in Go to represent an initializing declaration.
|
The ":=" operator is used a lot in Go to represent an initializing declaration.
|
||||||
There's one in the "for" clause on the next line:
|
There's one in the "for" clause on the next line:
|
||||||
@ -208,8 +208,8 @@ reassigning it. This snippet from "strings.go" is legal code:
|
|||||||
However the following statements are illegal because they would modify
|
However the following statements are illegal because they would modify
|
||||||
a "string" value:
|
a "string" value:
|
||||||
|
|
||||||
s[0] = 'x';
|
s[0] = 'x'
|
||||||
(*p)[1] = 'y';
|
(*p)[1] = 'y'
|
||||||
|
|
||||||
In C++ terms, Go strings are a bit like "const strings", while pointers
|
In C++ terms, Go strings are a bit like "const strings", while pointers
|
||||||
to strings are analogous to "const string" references.
|
to strings are analogous to "const string" references.
|
||||||
@ -219,7 +219,7 @@ read on.
|
|||||||
|
|
||||||
Arrays are declared like this:
|
Arrays are declared like this:
|
||||||
|
|
||||||
var arrayOfInt [10]int;
|
var arrayOfInt [10]int
|
||||||
|
|
||||||
Arrays, like strings, are values, but they are mutable. This differs
|
Arrays, like strings, are values, but they are mutable. This differs
|
||||||
from C, in which "arrayOfInt" would be usable as a pointer to "int".
|
from C, in which "arrayOfInt" would be usable as a pointer to "int".
|
||||||
@ -271,13 +271,13 @@ pointer to "sum()" by (implicitly) promoting it to a slice.
|
|||||||
If you are creating a regular array but want the compiler to count the
|
If you are creating a regular array but want the compiler to count the
|
||||||
elements for you, use "..." as the array size:
|
elements for you, use "..." as the array size:
|
||||||
|
|
||||||
s := sum(&[...]int{1,2,3});
|
s := sum(&[...]int{1,2,3})
|
||||||
|
|
||||||
In practice, though, unless you're meticulous about storage layout within a
|
In practice, though, unless you're meticulous about storage layout within a
|
||||||
data structure, a slice itself—using empty brackets and no
|
data structure, a slice itself—using empty brackets and no
|
||||||
"&"—is all you need:
|
"&"—is all you need:
|
||||||
|
|
||||||
s := sum([]int{1,2,3});
|
s := sum([]int{1,2,3})
|
||||||
|
|
||||||
There are also maps, which you can initialize like this:
|
There are also maps, which you can initialize like this:
|
||||||
|
|
||||||
@ -312,23 +312,23 @@ To allocate a new variable, use "new()", which
|
|||||||
returns a pointer to the allocated storage.
|
returns a pointer to the allocated storage.
|
||||||
|
|
||||||
type T struct { a, b int }
|
type T struct { a, b int }
|
||||||
var t *T = new(T);
|
var t *T = new(T)
|
||||||
|
|
||||||
or the more idiomatic
|
or the more idiomatic
|
||||||
|
|
||||||
t := new(T);
|
t := new(T)
|
||||||
|
|
||||||
Some types—maps, slices, and channels (see below)—have reference semantics.
|
Some types—maps, slices, and channels (see below)—have reference semantics.
|
||||||
If you're holding a slice or a map and you modify its contents, other variables
|
If you're holding a slice or a map and you modify its contents, other variables
|
||||||
referencing the same underlying data will see the modification. For these three
|
referencing the same underlying data will see the modification. For these three
|
||||||
types you want to use the built-in function "make()":
|
types you want to use the built-in function "make()":
|
||||||
|
|
||||||
m := make(map[string]int);
|
m := make(map[string]int)
|
||||||
|
|
||||||
This statement initializes a new map ready to store entries.
|
This statement initializes a new map ready to store entries.
|
||||||
If you just declare the map, as in
|
If you just declare the map, as in
|
||||||
|
|
||||||
var m map[string]int;
|
var m map[string]int
|
||||||
|
|
||||||
it creates a "nil" reference that cannot hold anything. To use the map,
|
it creates a "nil" reference that cannot hold anything. To use the map,
|
||||||
you must first initialize the reference using "make()" or by assignment from an
|
you must first initialize the reference using "make()" or by assignment from an
|
||||||
@ -410,9 +410,9 @@ filled in. This code uses Go's notion of a ''composite literal'', analogous to
|
|||||||
the ones used to build maps and arrays, to construct a new heap-allocated
|
the ones used to build maps and arrays, to construct a new heap-allocated
|
||||||
object. We could write
|
object. We could write
|
||||||
|
|
||||||
n := new(File);
|
n := new(File)
|
||||||
n.fd = fd;
|
n.fd = fd
|
||||||
n.name = name;
|
n.name = name
|
||||||
return n
|
return n
|
||||||
|
|
||||||
but for simple structures like "File" it's easier to return the address of a nonce
|
but for simple structures like "File" it's easier to return the address of a nonce
|
||||||
@ -696,7 +696,7 @@ Schematically, given a value "v", it does this:
|
|||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
s, ok := v.(Stringer); // Test whether v implements "String()"
|
s, ok := v.(Stringer) // Test whether v implements "String()"
|
||||||
if ok {
|
if ok {
|
||||||
result = s.String()
|
result = s.String()
|
||||||
} else {
|
} else {
|
||||||
@ -721,7 +721,7 @@ not a file. Instead, it is a variable of type "io.Writer", which is an
|
|||||||
interface type defined in the "io" library:
|
interface type defined in the "io" library:
|
||||||
|
|
||||||
type Writer interface {
|
type Writer interface {
|
||||||
Write(p []byte) (n int, err os.Error);
|
Write(p []byte) (n int, err os.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
(This interface is another conventional name, this time for "Write"; there are also
|
(This interface is another conventional name, this time for "Write"; there are also
|
||||||
@ -787,15 +787,15 @@ invoke the function, prefixing the call with the keyword "go";
|
|||||||
this starts the function running in parallel with the current
|
this starts the function running in parallel with the current
|
||||||
computation but in the same address space:
|
computation but in the same address space:
|
||||||
|
|
||||||
go sum(hugeArray); // calculate sum in the background
|
go sum(hugeArray) // calculate sum in the background
|
||||||
|
|
||||||
If you want to know when the calculation is done, pass a channel
|
If you want to know when the calculation is done, pass a channel
|
||||||
on which it can report back:
|
on which it can report back:
|
||||||
|
|
||||||
ch := make(chan int);
|
ch := make(chan int)
|
||||||
go sum(hugeArray, ch);
|
go sum(hugeArray, ch)
|
||||||
// ... do something else for a while
|
// ... do something else for a while
|
||||||
result := <-ch; // wait for, and retrieve, result
|
result := <-ch // wait for, and retrieve, result
|
||||||
|
|
||||||
Back to our prime sieve. Here's how the sieve pipeline is stitched
|
Back to our prime sieve. Here's how the sieve pipeline is stitched
|
||||||
together:
|
together:
|
||||||
|
Loading…
Reference in New Issue
Block a user