mirror of
https://github.com/golang/go
synced 2024-11-22 01:04:40 -07:00
update tutorial
R=rsc DELTA=30 (5 added, 0 deleted, 25 changed) OCL=33138 CL=33170
This commit is contained in:
parent
43f29e64a6
commit
61028773b1
@ -139,12 +139,12 @@ set, it appends a newline, and then writes the result.
|
|||||||
|
|
||||||
Notice that "main.main" is a niladic function with no return type.
|
Notice that "main.main" is a niladic function with no return type.
|
||||||
It's defined that way. Falling off the end of "main.main" means
|
It's defined that way. Falling off the end of "main.main" means
|
||||||
''success''; if you want to signal erroneous return, use
|
''success''; if you want to signal an erroneous return, call
|
||||||
|
|
||||||
sys.Exit(1)
|
os.Exit(1)
|
||||||
|
|
||||||
The "sys" package is built in and contains some essentials for getting
|
The "os" package contains other essentials for getting
|
||||||
started; for instance, "sys.Args" is an array used by the
|
started; for instance, "os.Args" is an array used by the
|
||||||
"flag" package to access the command-line arguments.
|
"flag" package to access the command-line arguments.
|
||||||
|
|
||||||
An Interlude about Types
|
An Interlude about Types
|
||||||
@ -261,7 +261,7 @@ 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()":
|
||||||
@ -385,9 +385,9 @@ be negative and "NewFile" will return "nil".
|
|||||||
About those errors: The "os" library includes a general notion of an error
|
About those errors: The "os" library includes a general notion of an error
|
||||||
string, maintaining a unique set of errors throughout the program. It's a
|
string, maintaining a unique set of errors throughout the program. It's a
|
||||||
good idea to use its facility in your own interfaces, as we do here, for
|
good idea to use its facility in your own interfaces, as we do here, for
|
||||||
consistent error handling throughout Go code. In "Open" we use the
|
consistent error handling throughout Go code. In "Open" we use a
|
||||||
routine "os.ErrnoToError" to translate Unix's integer "errno" value into
|
conversion to "os.Errno" to translate Unix's integer "errno" value into
|
||||||
an error string, which will be stored in a unique instance of "*os.Error".
|
an error value, which will be stored in a unique instance of type "os.Error".
|
||||||
|
|
||||||
Now that we can build "Files", we can write methods for them. To declare
|
Now that we can build "Files", we can write methods for them. To declare
|
||||||
a method of a type, we define a function to have an explicit receiver
|
a method of a type, we define a function to have an explicit receiver
|
||||||
@ -406,15 +406,18 @@ array, not just for "structs". We'll see an example with arrays later.
|
|||||||
The "String" method is so called because of printing convention we'll
|
The "String" method is so called because of printing convention we'll
|
||||||
describe later.
|
describe later.
|
||||||
|
|
||||||
The methods use the public variable "os.EINVAL" to return the ("*os.Error"
|
The methods use the public variable "os.EINVAL" to return the ("os.Error"
|
||||||
version of the) Unix error code EINVAL. The "os" library defines a standard
|
version of the) Unix error code "EINVAL". The "os" library defines a standard
|
||||||
set of such error values.
|
set of such error values.
|
||||||
|
|
||||||
Finally, we can use our new package:
|
We can now use our new package:
|
||||||
|
|
||||||
--PROG progs/helloworld3.go
|
--PROG progs/helloworld3.go
|
||||||
|
|
||||||
And now we can run the program:
|
The import of ''"./file"'' tells the compiler to use our own package rather than
|
||||||
|
something from the directory of installed packages.
|
||||||
|
|
||||||
|
Finally we can run the program:
|
||||||
|
|
||||||
% helloworld3
|
% helloworld3
|
||||||
hello, world
|
hello, world
|
||||||
@ -509,7 +512,7 @@ implement a "writer", or any other interface built from its methods that
|
|||||||
fits the current situation. Consider the <i>empty interface</i>
|
fits the current situation. Consider the <i>empty interface</i>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
type interface Empty {}
|
type Empty interface {}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<i>Every</i> type implements the empty interface, which makes it
|
<i>Every</i> type implements the empty interface, which makes it
|
||||||
@ -562,13 +565,13 @@ We've seen simple uses of the package "fmt", which
|
|||||||
implements "Printf", "Fprintf", and so on.
|
implements "Printf", "Fprintf", and so on.
|
||||||
Within the "fmt" package, "Printf" is declared with this signature:
|
Within the "fmt" package, "Printf" is declared with this signature:
|
||||||
|
|
||||||
Printf(format string, v ...) (n int, errno *os.Error)
|
Printf(format string, v ...) (n int, errno os.Error)
|
||||||
|
|
||||||
That "..." represents the variadic argument list that in C would
|
That "..." represents the variadic argument list that in C would
|
||||||
be handled using the "stdarg.h" macros, but in Go is passed using
|
be handled using the "stdarg.h" macros, but in Go is passed using
|
||||||
an empty interface variable ("interface {}") that is then unpacked
|
an empty interface variable ("interface {}") that is then unpacked
|
||||||
using the reflection library. It's off topic here but the use of
|
using the reflection library. It's off topic here but the use of
|
||||||
reflection helps explain some of the nice properties of Go's Printf,
|
reflection helps explain some of the nice properties of Go's "Printf",
|
||||||
due to the ability of "Printf" to discover the type of its arguments
|
due to the ability of "Printf" to discover the type of its arguments
|
||||||
dynamically.
|
dynamically.
|
||||||
|
|
||||||
@ -661,7 +664,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
|
||||||
@ -756,7 +759,9 @@ returns the channel to the caller. It is a factory for concurrent
|
|||||||
execution, starting the goroutine and returning its connection.
|
execution, starting the goroutine and returning its connection.
|
||||||
|
|
||||||
The function literal notation (lines 8-12) allows us to construct an
|
The function literal notation (lines 8-12) allows us to construct an
|
||||||
anonymous function and invoke it on the spot.
|
anonymous function and invoke it on the spot. Notice that the local
|
||||||
|
variable "ch" is available to the function literal and lives on even
|
||||||
|
after "generate" returns.
|
||||||
|
|
||||||
The same change can be made to "filter":
|
The same change can be made to "filter":
|
||||||
|
|
||||||
|
@ -9,37 +9,37 @@ import "fmt"
|
|||||||
// Send the sequence 2, 3, 4, ... to returned channel
|
// Send the sequence 2, 3, 4, ... to returned channel
|
||||||
func generate() chan int {
|
func generate() chan int {
|
||||||
ch := make(chan int);
|
ch := make(chan int);
|
||||||
go func(ch chan int){
|
go func(){
|
||||||
for i := 2; ; i++ {
|
for i := 2; ; i++ {
|
||||||
ch <- i
|
ch <- i
|
||||||
}
|
}
|
||||||
}(ch);
|
}();
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter out input values divisible by 'prime', send rest to returned channel
|
// Filter out input values divisible by 'prime', send rest to returned channel
|
||||||
func filter(in chan int, prime int) chan int {
|
func filter(in chan int, prime int) chan int {
|
||||||
out := make(chan int);
|
out := make(chan int);
|
||||||
go func(in chan int, out chan int, prime int) {
|
go func() {
|
||||||
for {
|
for {
|
||||||
if i := <-in; i % prime != 0 {
|
if i := <-in; i % prime != 0 {
|
||||||
out <- i
|
out <- i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}(in, out, prime);
|
}();
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
func sieve() chan int {
|
func sieve() chan int {
|
||||||
out := make(chan int);
|
out := make(chan int);
|
||||||
go func(out chan int) {
|
go func() {
|
||||||
ch := generate();
|
ch := generate();
|
||||||
for {
|
for {
|
||||||
prime := <-ch;
|
prime := <-ch;
|
||||||
out <- prime;
|
out <- prime;
|
||||||
ch = filter(ch, prime);
|
ch = filter(ch, prime);
|
||||||
}
|
}
|
||||||
}(out);
|
}();
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user