blob: 858958d98d6377f73ca664d5166a91f5450860db [file] [log] [blame]
Rob Pikecf164432009-11-12 11:05:20 -08001<!-- A Tutorial for the Go Programming Language -->
Rob Pikebf983a02009-10-13 22:10:16 -07002Introduction
Rob Pikeae4123f2008-09-10 11:46:05 -07003----
4
Rob Pike83f0b712009-11-01 20:47:03 -08005This document is a tutorial introduction to the basics of the Go programming
Rob Pike27a56172008-09-10 17:11:04 -07006language, intended for programmers familiar with C or C++. It is not a comprehensive
Rob Pike327b6c62009-10-13 18:01:24 -07007guide to the language; at the moment the document closest to that is the
Rob Pike83f0b712009-11-01 20:47:03 -08008<a href='/doc/go_spec.html'>language specification</a>.
Rob Pike7115eef2011-02-14 11:25:00 -08009After you've read this tutorial, you should look at
Rob Pike83f0b712009-11-01 20:47:03 -080010<a href='/doc/effective_go.html'>Effective Go</a>,
Rob Pike7115eef2011-02-14 11:25:00 -080011which digs deeper into how the language is used and
12talks about the style and idioms of programming in Go.
13Also, slides from a 3-day course about Go are available.
Rob Pike9b409ac2011-06-10 15:05:51 +100014They provide some background and a lot of examples:
Rob Pike0d93dbc2009-11-08 22:03:12 -080015<a href='/doc/GoCourseDay1.pdf'>Day 1</a>,
16<a href='/doc/GoCourseDay2.pdf'>Day 2</a>,
17<a href='/doc/GoCourseDay3.pdf'>Day 3</a>.
Rob Pike27a56172008-09-10 17:11:04 -070018
Rob Pike83f0b712009-11-01 20:47:03 -080019The presentation here proceeds through a series of modest programs to illustrate
Rob Pike27a56172008-09-10 17:11:04 -070020key features of the language. All the programs work (at time of writing) and are
Rob Pikebf983a02009-10-13 22:10:16 -070021checked into the repository in the directory <a href='/doc/progs'>"/doc/progs/"</a>.
Rob Pike27a56172008-09-10 17:11:04 -070022
Rob Pike27a56172008-09-10 17:11:04 -070023Hello, World
24----
25
26Let's start in the usual way:
Rob Pikeae4123f2008-09-10 11:46:05 -070027
Rob Pike9cf37c32011-07-04 16:15:14 +100028!src progs/helloworld.go /package/ $
Rob Pikeae4123f2008-09-10 11:46:05 -070029
Rob Pike6aabf312009-02-04 15:13:07 -080030Every Go source file declares, using a "package" statement, which package it's part of.
Ian Lance Taylor97a55a72009-11-08 21:00:45 -080031It may also import other packages to use their facilities.
Rob Pikebdbb3b42009-03-18 14:09:16 -070032This program imports the package "fmt" to gain access to
Ian Lance Taylor97a55a72009-11-08 21:00:45 -080033our old, now capitalized and package-qualified, friend, "fmt.Printf".
Rob Pikeae4123f2008-09-10 11:46:05 -070034
Ian Lance Taylor97a55a72009-11-08 21:00:45 -080035Functions are introduced with the "func" keyword.
36The "main" package's "main" function is where the program starts running (after
37any initialization).
Rob Pikeae4123f2008-09-10 11:46:05 -070038
Russ Cox898714a2009-11-07 18:05:30 -080039String constants can contain Unicode characters, encoded in UTF-8.
40(In fact, Go source files are defined to be encoded in UTF-8.)
Rob Pikeae4123f2008-09-10 11:46:05 -070041
Rob Pike27a56172008-09-10 17:11:04 -070042The comment convention is the same as in C++:
43
44 /* ... */
45 // ...
46
Rob Pike40d54352009-01-09 15:16:31 -080047Later we'll have much more to say about printing.
48
Rob Pike34356e92009-12-16 10:29:53 +110049Semicolons
50----
51
52You might have noticed that our program has no semicolons. In Go
53code, the only place you typically see semicolons is separating the
54clauses of "for" loops and the like; they are not necessary after
55every statement.
56
57In fact, what happens is that the formal language uses semicolons,
58much as in C or Java, but they are inserted automatically
59at the end of every line that looks like the end of a statement. You
60don't need to type them yourself.
61
62For details about how this is done you can see the language
63specification, but in practice all you need to know is that you
64never need to put a semicolon at the end of a line. (You can put
65them in if you want to write multiple statements per line.) As an
66extra help, you can also leave out a semicolon immediately before
67a closing brace.
68
69This approach makes for clean-looking, semicolon-free code. The
70one surprise is that it's important to put the opening
71brace of a construct such as an "if" statement on the same line as
72the "if"; if you don't, there are situations that may not compile
73or may give the wrong result. The language forces the brace style
74to some extent.
75
Rob Pike83f0b712009-11-01 20:47:03 -080076Compiling
77----
78
79Go is a compiled language. At the moment there are two compilers.
80"Gccgo" is a Go compiler that uses the GCC back end. There is also a
81suite of compilers with different (and odd) names for each architecture:
82"6g" for the 64-bit x86, "8g" for the 32-bit x86, and more. These
83compilers run significantly faster but generate less efficient code
84than "gccgo". At the time of writing (late 2009), they also have
85a more robust run-time system although "gccgo" is catching up.
86
87Here's how to compile and run our program. With "6g", say,
88
89 $ 6g helloworld.go # compile; object goes into helloworld.6
90 $ 6l helloworld.6 # link; output goes into 6.out
91 $ 6.out
92 Hello, world; or Καλημέρα κόσμε; or こんにちは 世界
93 $
94
95With "gccgo" it looks a little more traditional.
96
97 $ gccgo helloworld.go
98 $ a.out
99 Hello, world; or Καλημέρα κόσμε; or こんにちは 世界
100 $
101
Rob Pike27a56172008-09-10 17:11:04 -0700102Echo
103----
104
105Next up, here's a version of the Unix utility "echo(1)":
106
Rob Pike9cf37c32011-07-04 16:15:14 +1000107!src progs/echo.go /package/ $
Rob Pike27a56172008-09-10 17:11:04 -0700108
Rob Pike40d54352009-01-09 15:16:31 -0800109This program is small but it's doing a number of new things. In the last example,
Rob Pike83f0b712009-11-01 20:47:03 -0800110we saw "func" introduce a function. The keywords "var", "const", and "type"
Rob Pike27a56172008-09-10 17:11:04 -0700111(not used yet) also introduce declarations, as does "import".
112Notice that we can group declarations of the same sort into
Rob Pike9cf37c32011-07-04 16:15:14 +1000113parenthesized lists, one item per line, as in the "import" and "const" clauses here.
Rob Pike27a56172008-09-10 17:11:04 -0700114But it's not necessary to do so; we could have said
115
116 const Space = " "
117 const Newline = "\n"
118
Rob Pikebdbb3b42009-03-18 14:09:16 -0700119This program imports the "&quot;os&quot;" package to access its "Stdout" variable, of type
120"*os.File". The "import" statement is actually a declaration: in its general form,
121as used in our ``hello world'' program,
122it names the identifier ("fmt")
123that will be used to access members of the package imported from the file ("&quot;fmt&quot;"),
124found in the current directory or in a standard location.
125In this program, though, we've dropped the explicit name from the imports; by default,
Rob Pike40d54352009-01-09 15:16:31 -0800126packages are imported using the name defined by the imported package,
Rob Pikebdbb3b42009-03-18 14:09:16 -0700127which by convention is of course the file name itself. Our ``hello world'' program
128could have said just "import &quot;fmt&quot;".
129
130You can specify your
Rob Pike40d54352009-01-09 15:16:31 -0800131own import names if you want but it's only necessary if you need to resolve
132a naming conflict.
133
Rob Pikebdbb3b42009-03-18 14:09:16 -0700134Given "os.Stdout" we can use its "WriteString" method to print the string.
135
Rob Pikec17347e2011-07-09 23:17:38 +1000136After importing the "flag" package, we use a "var" declaration
137to create and initialize a global variable, called "omitNewline",
138to hold the value of echo's "-n" flag.
139The variable has type "*bool", pointer to "bool".
Rob Pike27a56172008-09-10 17:11:04 -0700140
Rob Pikec17347e2011-07-09 23:17:38 +1000141In "main.main", we parse the arguments (the call to "flag.Parse") and then create a local
142string variable with which to build the output.
Rob Pike27a56172008-09-10 17:11:04 -0700143
144The declaration statement has the form
145
Andrew Gerranda8234962010-04-28 10:50:44 +1000146 var s string = ""
Rob Pike27a56172008-09-10 17:11:04 -0700147
148This is the "var" keyword, followed by the name of the variable, followed by
149its type, followed by an equals sign and an initial value for the variable.
150
151Go tries to be terse, and this declaration could be shortened. Since the
152string constant is of type string, we don't have to tell the compiler that.
153We could write
154
Andrew Gerranda8234962010-04-28 10:50:44 +1000155 var s = ""
Rob Pike27a56172008-09-10 17:11:04 -0700156
157or we could go even shorter and write the idiom
158
Andrew Gerranda8234962010-04-28 10:50:44 +1000159 s := ""
Rob Pike27a56172008-09-10 17:11:04 -0700160
Rob Pike40d54352009-01-09 15:16:31 -0800161The ":=" operator is used a lot in Go to represent an initializing declaration.
Rob Pike40d54352009-01-09 15:16:31 -0800162There's one in the "for" clause on the next line:
Rob Pike27a56172008-09-10 17:11:04 -0700163
Rob Pike9cf37c32011-07-04 16:15:14 +1000164!src progs/echo.go /for/
Rob Pike27a56172008-09-10 17:11:04 -0700165
Rob Pike40d54352009-01-09 15:16:31 -0800166The "flag" package has parsed the arguments and left the non-flag arguments
Rob Pikec7ebfed2008-09-11 10:21:02 -0700167in a list that can be iterated over in the obvious way.
Rob Pike27a56172008-09-10 17:11:04 -0700168
169The Go "for" statement differs from that of C in a number of ways. First,
170it's the only looping construct; there is no "while" or "do". Second,
171there are no parentheses on the clause, but the braces on the body
Rob Pike40d54352009-01-09 15:16:31 -0800172are mandatory. The same applies to the "if" and "switch" statements.
173Later examples will show some other ways "for" can be written.
Rob Pike27a56172008-09-10 17:11:04 -0700174
Rob Pike40d54352009-01-09 15:16:31 -0800175The body of the loop builds up the string "s" by appending (using "+=")
Rob Pikef81abb92010-06-05 12:06:18 -0700176the arguments and separating spaces. After the loop, if the "-n" flag is not
Rob Pike83f0b712009-11-01 20:47:03 -0800177set, the program appends a newline. Finally, it writes the result.
Rob Pike27a56172008-09-10 17:11:04 -0700178
179Notice that "main.main" is a niladic function with no return type.
180It's defined that way. Falling off the end of "main.main" means
Rob Pike61028772009-08-13 08:54:26 -0700181''success''; if you want to signal an erroneous return, call
Rob Pike27a56172008-09-10 17:11:04 -0700182
Rob Pike61028772009-08-13 08:54:26 -0700183 os.Exit(1)
Rob Pike27a56172008-09-10 17:11:04 -0700184
Rob Pike61028772009-08-13 08:54:26 -0700185The "os" package contains other essentials for getting
Russ Cox898714a2009-11-07 18:05:30 -0800186started; for instance, "os.Args" is a slice used by the
Rob Pikeae05f002009-01-20 19:32:36 -0800187"flag" package to access the command-line arguments.
Rob Pike27a56172008-09-10 17:11:04 -0700188
Rob Pikec7ebfed2008-09-11 10:21:02 -0700189An Interlude about Types
190----
191
Rob Pike80e25fc2011-01-19 23:07:38 -0500192Go has some familiar types such as "int" and "uint" (unsigned "int"), which represent
Rob Pikec7ebfed2008-09-11 10:21:02 -0700193values of the ''appropriate'' size for the machine. It also defines
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800194explicitly-sized types such as "int8", "float64", and so on, plus
Rob Pike80e25fc2011-01-19 23:07:38 -0500195unsigned integer types such as "uint", "uint32", etc.
196These are distinct types; even if "int" and "int32" are both 32 bits in size,
Rob Pike40d54352009-01-09 15:16:31 -0800197they are not the same type. There is also a "byte" synonym for
198"uint8", which is the element type for strings.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700199
Rob Pike80e25fc2011-01-19 23:07:38 -0500200Floating-point types are always sized: "float32" and "float64",
201plus "complex64" (two "float32s") and "complex128"
202(two "float64s"). Complex numbers are outside the
203scope of this tutorial.
204
Rob Pikec7ebfed2008-09-11 10:21:02 -0700205Speaking of "string", that's a built-in type as well. Strings are
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800206<i>immutable values</i>&mdash;they are not just arrays of "byte" values.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700207Once you've built a string <i>value</i>, you can't change it, although
208of course you can change a string <i>variable</i> simply by
209reassigning it. This snippet from "strings.go" is legal code:
210
Rob Pike9cf37c32011-07-04 16:15:14 +1000211!src progs/strings.go /hello/ /ciao/
Rob Pikec7ebfed2008-09-11 10:21:02 -0700212
213However the following statements are illegal because they would modify
214a "string" value:
215
Andrew Gerranda8234962010-04-28 10:50:44 +1000216 s[0] = 'x'
217 (*p)[1] = 'y'
Rob Pikec7ebfed2008-09-11 10:21:02 -0700218
219In C++ terms, Go strings are a bit like "const strings", while pointers
220to strings are analogous to "const string" references.
221
222Yes, there are pointers. However, Go simplifies their use a little;
223read on.
224
225Arrays are declared like this:
226
Andrew Gerranda8234962010-04-28 10:50:44 +1000227 var arrayOfInt [10]int
Rob Pikec7ebfed2008-09-11 10:21:02 -0700228
229Arrays, like strings, are values, but they are mutable. This differs
Russ Cox898714a2009-11-07 18:05:30 -0800230from C, in which "arrayOfInt" would be usable as a pointer to "int".
Rob Pikec7ebfed2008-09-11 10:21:02 -0700231In Go, since arrays are values, it's meaningful (and useful) to talk
232about pointers to arrays.
233
234The size of the array is part of its type; however, one can declare
Rob Pike781462d2010-09-10 13:53:18 +1000235a <i>slice</i> variable to hold a reference to any array, of any size,
236with the same element type.
237A <i>slice
238expression</i> has the form "a[low : high]", representing
239the internal array indexed from "low" through "high-1"; the resulting
240slice is indexed from "0" through "high-low-1".
241In short, slices look a lot like arrays but with
Rob Pike40d54352009-01-09 15:16:31 -0800242no explicit size ("[]" vs. "[10]") and they reference a segment of
Rob Pike781462d2010-09-10 13:53:18 +1000243an underlying, usually anonymous, regular array. Multiple slices
Rob Pike40d54352009-01-09 15:16:31 -0800244can share data if they represent pieces of the same array;
245multiple arrays can never share data.
246
Russ Cox898714a2009-11-07 18:05:30 -0800247Slices are much more common in Go programs than
Rob Pike40d54352009-01-09 15:16:31 -0800248regular arrays; they're more flexible, have reference semantics,
249and are efficient. What they lack is the precise control of storage
250layout of a regular array; if you want to have a hundred elements
251of an array stored within your structure, you should use a regular
Rob Pike781462d2010-09-10 13:53:18 +1000252array. To create one, use a compound value <i>constructor</i>&mdash;an
253expression formed
254from a type followed by a brace-bounded expression like this:
255
256 [3]int{1,2,3}
257
258In this case the constructor builds an array of 3 "ints".
Rob Pike40d54352009-01-09 15:16:31 -0800259
260When passing an array to a function, you almost always want
Rob Pikedfff1822009-04-15 20:53:07 -0700261to declare the formal parameter to be a slice. When you call
Rob Pike781462d2010-09-10 13:53:18 +1000262the function, slice the array to create
263(efficiently) a slice reference and pass that.
264By default, the lower and upper bounds of a slice match the
265ends of the existing object, so the concise notation "[:]"
266will slice the whole array.
Rob Pike40d54352009-01-09 15:16:31 -0800267
268Using slices one can write this function (from "sum.go"):
Rob Pikec7ebfed2008-09-11 10:21:02 -0700269
Rob Pike9cf37c32011-07-04 16:15:14 +1000270!src progs/sum.go /sum/ /^}/
Rob Pikec7ebfed2008-09-11 10:21:02 -0700271
Rob Pike46f482a2011-05-25 06:44:09 +1000272Note how the return type ("int") is defined for "sum" by stating it
Rob Pike40d54352009-01-09 15:16:31 -0800273after the parameter list.
Rob Pike781462d2010-09-10 13:53:18 +1000274
275To call the function, we slice the array. This intricate call (we'll show
276a simpler way in a moment) constructs
277an array and slices it:
278
279 s := sum([3]int{1,2,3}[:])
Rob Pikec7ebfed2008-09-11 10:21:02 -0700280
Rob Pike40d54352009-01-09 15:16:31 -0800281If you are creating a regular array but want the compiler to count the
282elements for you, use "..." as the array size:
283
Rob Pike781462d2010-09-10 13:53:18 +1000284 s := sum([...]int{1,2,3}[:])
Rob Pike40d54352009-01-09 15:16:31 -0800285
Rob Pike781462d2010-09-10 13:53:18 +1000286That's fussier than necessary, though.
287In practice, unless you're meticulous about storage layout within a
288data structure, a slice itself&mdash;using empty brackets with no size&mdash;is all you need:
Rob Pike40d54352009-01-09 15:16:31 -0800289
Andrew Gerranda8234962010-04-28 10:50:44 +1000290 s := sum([]int{1,2,3})
Rob Pike40d54352009-01-09 15:16:31 -0800291
292There are also maps, which you can initialize like this:
Rob Pikec7ebfed2008-09-11 10:21:02 -0700293
Rob Pike83f0b712009-11-01 20:47:03 -0800294 m := map[string]int{"one":1 , "two":2}
Rob Pikec7ebfed2008-09-11 10:21:02 -0700295
Rob Pike46f482a2011-05-25 06:44:09 +1000296The built-in function "len", which returns number of elements,
Rob Pike40d54352009-01-09 15:16:31 -0800297makes its first appearance in "sum". It works on strings, arrays,
Russ Cox898714a2009-11-07 18:05:30 -0800298slices, maps, and channels.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700299
Rob Pikecf164432009-11-12 11:05:20 -0800300By the way, another thing that works on strings, arrays, slices, maps
301and channels is the "range" clause on "for" loops. Instead of writing
302
Rob Pikebbd4cb32009-12-14 13:30:11 +1100303 for i := 0; i &lt; len(a); i++ { ... }
Rob Pikecf164432009-11-12 11:05:20 -0800304
305to loop over the elements of a slice (or map or ...) , we could write
306
307 for i, v := range a { ... }
308
309This assigns "i" to the index and "v" to the value of the successive
310elements of the target of the range. See
311<a href='/doc/effective_go.html'>Effective Go</a>
312for more examples of its use.
313
Rob Pikec7ebfed2008-09-11 10:21:02 -0700314
Rob Pike40d54352009-01-09 15:16:31 -0800315An Interlude about Allocation
316----
Rob Pikec7ebfed2008-09-11 10:21:02 -0700317
Rob Pike40d54352009-01-09 15:16:31 -0800318Most types in Go are values. If you have an "int" or a "struct"
319or an array, assignment
Russ Cox898714a2009-11-07 18:05:30 -0800320copies the contents of the object.
Rob Pike46f482a2011-05-25 06:44:09 +1000321To allocate a new variable, use the built-in function "new", which
Rob Pike40d54352009-01-09 15:16:31 -0800322returns a pointer to the allocated storage.
323
324 type T struct { a, b int }
Andrew Gerranda8234962010-04-28 10:50:44 +1000325 var t *T = new(T)
Rob Pike40d54352009-01-09 15:16:31 -0800326
327or the more idiomatic
328
Andrew Gerranda8234962010-04-28 10:50:44 +1000329 t := new(T)
Rob Pike40d54352009-01-09 15:16:31 -0800330
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800331Some types&mdash;maps, slices, and channels (see below)&mdash;have reference semantics.
Rob Pike40d54352009-01-09 15:16:31 -0800332If you're holding a slice or a map and you modify its contents, other variables
Rob Pike6aabf312009-02-04 15:13:07 -0800333referencing the same underlying data will see the modification. For these three
Rob Pike46f482a2011-05-25 06:44:09 +1000334types you want to use the built-in function "make":
Rob Pike40d54352009-01-09 15:16:31 -0800335
Andrew Gerranda8234962010-04-28 10:50:44 +1000336 m := make(map[string]int)
Rob Pike40d54352009-01-09 15:16:31 -0800337
Rob Pike6aabf312009-02-04 15:13:07 -0800338This statement initializes a new map ready to store entries.
339If you just declare the map, as in
Rob Pike40d54352009-01-09 15:16:31 -0800340
Andrew Gerranda8234962010-04-28 10:50:44 +1000341 var m map[string]int
Rob Pike40d54352009-01-09 15:16:31 -0800342
Rob Pike6aabf312009-02-04 15:13:07 -0800343it creates a "nil" reference that cannot hold anything. To use the map,
Rob Pike46f482a2011-05-25 06:44:09 +1000344you must first initialize the reference using "make" or by assignment from an
Rob Pike40d54352009-01-09 15:16:31 -0800345existing map.
346
Rob Pike6aabf312009-02-04 15:13:07 -0800347Note that "new(T)" returns type "*T" while "make(T)" returns type
Rob Pike46f482a2011-05-25 06:44:09 +1000348"T". If you (mistakenly) allocate a reference object with "new" rather than "make",
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800349you receive a pointer to a nil reference, equivalent to
Rob Pike6aabf312009-02-04 15:13:07 -0800350declaring an uninitialized variable and taking its address.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700351
352An Interlude about Constants
353----
354
355Although integers come in lots of sizes in Go, integer constants do not.
Rob Pike83f0b712009-11-01 20:47:03 -0800356There are no constants like "0LL" or "0x0UL". Instead, integer
Robert Griesemer84033302009-10-01 16:58:17 -0700357constants are evaluated as large-precision values that
Rob Pikedb9002f2008-09-16 11:00:11 -0700358can overflow only when they are assigned to an integer variable with
359too little precision to represent the value.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700360
Russ Cox898714a2009-11-07 18:05:30 -0800361 const hardEight = (1 &lt;&lt; 100) &gt;&gt; 97 // legal
Rob Pikec7ebfed2008-09-11 10:21:02 -0700362
363There are nuances that deserve redirection to the legalese of the
364language specification but here are some illustrative examples:
365
366 var a uint64 = 0 // a has type uint64, value 0
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800367 a := uint64(0) // equivalent; uses a "conversion"
Rob Pikec7ebfed2008-09-11 10:21:02 -0700368 i := 0x1234 // i gets default type: int
369 var j int = 1e6 // legal - 1000000 is representable in an int
Rob Pike80e25fc2011-01-19 23:07:38 -0500370 x := 1.5 // a float64, the default type for floating constants
Rob Pike40d54352009-01-09 15:16:31 -0800371 i3div2 := 3/2 // integer division - result is 1
Rob Pike80e25fc2011-01-19 23:07:38 -0500372 f3div2 := 3./2. // floating-point division - result is 1.5
Rob Pikec7ebfed2008-09-11 10:21:02 -0700373
Rob Pike40d54352009-01-09 15:16:31 -0800374Conversions only work for simple cases such as converting "ints" of one
Rob Pike80e25fc2011-01-19 23:07:38 -0500375sign or size to another and between integers and floating-point numbers,
376plus a couple of other instances outside the scope of a tutorial.
377There are no automatic numeric conversions of any kind in Go,
Rob Pikec7ebfed2008-09-11 10:21:02 -0700378other than that of making constants have concrete size and type when
379assigned to a variable.
Rob Pike66937302008-09-12 16:03:16 -0700380
381An I/O Package
382----
383
Rob Pike23fc9c82011-04-18 10:51:40 -0700384Next we'll look at a simple package for doing file I/O with an
385open/close/read/write interface. Here's the start of "file.go":
Rob Pike66937302008-09-12 16:03:16 -0700386
Rob Pike9cf37c32011-07-04 16:15:14 +1000387!src progs/file.go /package/ /^}/
Rob Pike66937302008-09-12 16:03:16 -0700388
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800389The first few lines declare the name of the
390package&mdash;"file"&mdash;and then import two packages. The "os"
391package hides the differences
Rob Pike40d54352009-01-09 15:16:31 -0800392between various operating systems to give a consistent view of files and
Russ Cox898714a2009-11-07 18:05:30 -0800393so on; here we're going to use its error handling utilities
Rob Pike40d54352009-01-09 15:16:31 -0800394and reproduce the rudiments of its file I/O.
395
396The other item is the low-level, external "syscall" package, which provides
Rob Pike66937302008-09-12 16:03:16 -0700397a primitive interface to the underlying operating system's calls.
398
399Next is a type definition: the "type" keyword introduces a type declaration,
Rob Pikee9f4fb22009-03-16 22:53:23 -0700400in this case a data structure called "File".
401To make things a little more interesting, our "File" includes the name of the file
Rob Pikeae05f002009-01-20 19:32:36 -0800402that the file descriptor refers to.
Rob Pike66937302008-09-12 16:03:16 -0700403
Rob Pikee9f4fb22009-03-16 22:53:23 -0700404Because "File" starts with a capital letter, the type is available outside the package,
Rob Pikeae05f002009-01-20 19:32:36 -0800405that is, by users of the package. In Go the rule about visibility of information is
Rob Pike83f0b712009-11-01 20:47:03 -0800406simple: if a name (of a top-level type, function, method, constant or variable, or of
407a structure field or method) is capitalized, users of the package may see it. Otherwise, the
Rob Pikeae05f002009-01-20 19:32:36 -0800408name and hence the thing being named is visible only inside the package in which
Rob Pike6aabf312009-02-04 15:13:07 -0800409it is declared. This is more than a convention; the rule is enforced by the compiler.
410In Go, the term for publicly visible names is ''exported''.
Rob Pike66937302008-09-12 16:03:16 -0700411
Rob Pikee9f4fb22009-03-16 22:53:23 -0700412In the case of "File", all its fields are lower case and so invisible to users, but we
Rob Pikeae05f002009-01-20 19:32:36 -0800413will soon give it some exported, upper-case methods.
414
Russ Cox898714a2009-11-07 18:05:30 -0800415First, though, here is a factory to create a "File":
Rob Pikeae05f002009-01-20 19:32:36 -0800416
Rob Pike9cf37c32011-07-04 16:15:14 +1000417!src progs/file.go /newFile/ /^}/
Rob Pike66937302008-09-12 16:03:16 -0700418
Rob Pikee9f4fb22009-03-16 22:53:23 -0700419This returns a pointer to a new "File" structure with the file descriptor and name
Rob Pike40d54352009-01-09 15:16:31 -0800420filled in. This code uses Go's notion of a ''composite literal'', analogous to
Rob Pike6aabf312009-02-04 15:13:07 -0800421the ones used to build maps and arrays, to construct a new heap-allocated
422object. We could write
Rob Pike40d54352009-01-09 15:16:31 -0800423
Andrew Gerranda8234962010-04-28 10:50:44 +1000424 n := new(File)
425 n.fd = fd
426 n.name = name
Rob Pike40d54352009-01-09 15:16:31 -0800427 return n
428
Andrew Gerrand7de5e6e2010-10-21 14:59:23 +1100429but for simple structures like "File" it's easier to return the address of a
Rob Pikec17347e2011-07-09 23:17:38 +1000430composite literal, as is done here in the "return" statement from "newFile".
Rob Pike40d54352009-01-09 15:16:31 -0800431
Rob Pikee9f4fb22009-03-16 22:53:23 -0700432We can use the factory to construct some familiar, exported variables of type "*File":
Rob Pike66937302008-09-12 16:03:16 -0700433
Rob Pike9cf37c32011-07-04 16:15:14 +1000434!src progs/file.go /var/ /^.$/
Rob Pike66937302008-09-12 16:03:16 -0700435
Rob Pikee9f4fb22009-03-16 22:53:23 -0700436The "newFile" function was not exported because it's internal. The proper,
Rob Pike23fc9c82011-04-18 10:51:40 -0700437exported factory to use is "OpenFile" (we'll explain that name in a moment):
Rob Pike66937302008-09-12 16:03:16 -0700438
Rob Pike9cf37c32011-07-04 16:15:14 +1000439!src progs/file.go /func.OpenFile/ /^}/
Rob Pike66937302008-09-12 16:03:16 -0700440
Rob Pike23fc9c82011-04-18 10:51:40 -0700441There are a number of new things in these few lines. First, "OpenFile" returns
Rob Pikecf164432009-11-12 11:05:20 -0800442multiple values, a "File" and an error (more about errors in a moment).
Rob Pike40d54352009-01-09 15:16:31 -0800443We declare the
444multi-value return as a parenthesized list of declarations; syntactically
445they look just like a second parameter list. The function
Rob Pikeae05f002009-01-20 19:32:36 -0800446"syscall.Open"
Rob Pike66937302008-09-12 16:03:16 -0700447also has a multi-value return, which we can grab with the multi-variable
Rob Pikec17347e2011-07-09 23:17:38 +1000448declaration on the first line; it declares "r" and "e" to hold the two values,
Russ Cox898714a2009-11-07 18:05:30 -0800449both of type "int" (although you'd have to look at the "syscall" package
Rob Pikec17347e2011-07-09 23:17:38 +1000450to see that). Finally, "OpenFile" returns two values: a pointer to the new "File"
Rob Pikeae05f002009-01-20 19:32:36 -0800451and the error. If "syscall.Open" fails, the file descriptor "r" will
Rob Pike8f478902009-11-13 16:00:55 -0800452be negative and "newFile" will return "nil".
Rob Pike66937302008-09-12 16:03:16 -0700453
Russ Cox898714a2009-11-07 18:05:30 -0800454About those errors: The "os" library includes a general notion of an error.
455It's a good idea to use its facility in your own interfaces, as we do here, for
Rob Pike61028772009-08-13 08:54:26 -0700456consistent error handling throughout Go code. In "Open" we use a
Russ Cox898714a2009-11-07 18:05:30 -0800457conversion to translate Unix's integer "errno" value into the integer type
458"os.Errno", which implements "os.Error".
Rob Pike40d54352009-01-09 15:16:31 -0800459
Rob Pike23fc9c82011-04-18 10:51:40 -0700460Why "OpenFile" and not "Open"? To mimic Go's "os" package, which
461our exercise is emulating. The "os" package takes the opportunity
462to make the two commonest cases - open for read and create for
463write - the simplest, just "Open" and "Create". "OpenFile" is the
464general case, analogous to the Unix system call "Open". Here is
465the implementation of our "Open" and "Create"; they're trivial
466wrappers that eliminate common errors by capturing
467the tricky standard arguments to open and, especially, to create a file:
468
Rob Pike9cf37c32011-07-04 16:15:14 +1000469!src progs/file.go /^const/ /^}/
Rob Pike23fc9c82011-04-18 10:51:40 -0700470
Rob Pike9cf37c32011-07-04 16:15:14 +1000471!src progs/file.go /func.Create/ /^}/
Rob Pike23fc9c82011-04-18 10:51:40 -0700472
473Back to our main story.
Rob Pikee9f4fb22009-03-16 22:53:23 -0700474Now that we can build "Files", we can write methods for them. To declare
Rob Pike66937302008-09-12 16:03:16 -0700475a method of a type, we define a function to have an explicit receiver
476of that type, placed
Rob Pikee9f4fb22009-03-16 22:53:23 -0700477in parentheses before the function name. Here are some methods for "*File",
478each of which declares a receiver variable "file".
Rob Pike66937302008-09-12 16:03:16 -0700479
Rob Pike9cf37c32011-07-04 16:15:14 +1000480!src progs/file.go /Close/ $
Rob Pike66937302008-09-12 16:03:16 -0700481
482There is no implicit "this" and the receiver variable must be used to access
483members of the structure. Methods are not declared within
484the "struct" declaration itself. The "struct" declaration defines only data members.
Russ Cox898714a2009-11-07 18:05:30 -0800485In fact, methods can be created for almost any type you name, such as an integer or
Rob Pike6aabf312009-02-04 15:13:07 -0800486array, not just for "structs". We'll see an example with arrays later.
Rob Pike40d54352009-01-09 15:16:31 -0800487
Rob Pike83f0b712009-11-01 20:47:03 -0800488The "String" method is so called because of a printing convention we'll
Rob Pike6aabf312009-02-04 15:13:07 -0800489describe later.
490
Rob Pike61028772009-08-13 08:54:26 -0700491The methods use the public variable "os.EINVAL" to return the ("os.Error"
492version of the) Unix error code "EINVAL". The "os" library defines a standard
Rob Pike40d54352009-01-09 15:16:31 -0800493set of such error values.
Rob Pike66937302008-09-12 16:03:16 -0700494
Rob Pike61028772009-08-13 08:54:26 -0700495We can now use our new package:
Rob Pike66937302008-09-12 16:03:16 -0700496
Rob Pike9cf37c32011-07-04 16:15:14 +1000497!src progs/helloworld3.go /package/ $
Rob Pike66937302008-09-12 16:03:16 -0700498
Rob Pike708d7162010-07-14 13:29:12 -0700499The ''"./"'' in the import of ''"./file"'' tells the compiler
500to use our own package rather than
Rob Pike61028772009-08-13 08:54:26 -0700501something from the directory of installed packages.
Rob Pike708d7162010-07-14 13:29:12 -0700502(Also, ''"file.go"'' must be compiled before we can import the
503package.)
Rob Pike61028772009-08-13 08:54:26 -0700504
Rob Pikeeaade072011-01-18 11:07:02 -0800505Now we can compile and run the program. On Unix, this would be the result:
Rob Pike66937302008-09-12 16:03:16 -0700506
Rob Pike708d7162010-07-14 13:29:12 -0700507 $ 6g file.go # compile file package
508 $ 6g helloworld3.go # compile main package
509 $ 6l -o helloworld3 helloworld3.6 # link - no need to mention "file"
510 $ helloworld3
Rob Pike66937302008-09-12 16:03:16 -0700511 hello, world
Rob Pike6aabf312009-02-04 15:13:07 -0800512 can't open file; err=No such file or directory
Rob Pike708d7162010-07-14 13:29:12 -0700513 $
Rob Pike66937302008-09-12 16:03:16 -0700514
Rob Pikea43033a2008-09-15 11:48:37 -0700515Rotting cats
516----
517
Rob Pikee9f4fb22009-03-16 22:53:23 -0700518Building on the "file" package, here's a simple version of the Unix utility "cat(1)",
Rob Pike40d54352009-01-09 15:16:31 -0800519"progs/cat.go":
Rob Pikea43033a2008-09-15 11:48:37 -0700520
Rob Pike9cf37c32011-07-04 16:15:14 +1000521!src progs/cat.go /package/ $
Rob Pikea43033a2008-09-15 11:48:37 -0700522
523By now this should be easy to follow, but the "switch" statement introduces some
524new features. Like a "for" loop, an "if" or "switch" can include an
Rob Pike9cf37c32011-07-04 16:15:14 +1000525initialization statement. The "switch" statement in "cat" uses one to create variables
526"nr" and "er" to hold the return values from the call to "f.Read". (The "if" a few lines later
Rob Pikea43033a2008-09-15 11:48:37 -0700527has the same idea.) The "switch" statement is general: it evaluates the cases
528from top to bottom looking for the first case that matches the value; the
Rob Pikedb9002f2008-09-16 11:00:11 -0700529case expressions don't need to be constants or even integers, as long as
530they all have the same type.
Rob Pikea43033a2008-09-15 11:48:37 -0700531
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800532Since the "switch" value is just "true", we could leave it off&mdash;as is also
Rob Pike40d54352009-01-09 15:16:31 -0800533the situation
Rob Pikea43033a2008-09-15 11:48:37 -0700534in a "for" statement, a missing value means "true". In fact, such a "switch"
Rob Pike40d54352009-01-09 15:16:31 -0800535is a form of "if-else" chain. While we're here, it should be mentioned that in
536"switch" statements each "case" has an implicit "break".
Rob Pikea43033a2008-09-15 11:48:37 -0700537
Rob Pike9cf37c32011-07-04 16:15:14 +1000538The argument to "file.Stdout.Write" is created by slicing the array "buf".
Rob Pike40d54352009-01-09 15:16:31 -0800539Slices provide the standard Go way to handle I/O buffers.
Rob Pikea43033a2008-09-15 11:48:37 -0700540
541Now let's make a variant of "cat" that optionally does "rot13" on its input.
542It's easy to do by just processing the bytes, but instead we will exploit
543Go's notion of an <i>interface</i>.
544
Rob Pike46f482a2011-05-25 06:44:09 +1000545The "cat" subroutine uses only two methods of "f": "Read" and "String",
Rob Pikea43033a2008-09-15 11:48:37 -0700546so let's start by defining an interface that has exactly those two methods.
547Here is code from "progs/cat_rot13.go":
548
Rob Pike9cf37c32011-07-04 16:15:14 +1000549!src progs/cat_rot13.go /type.reader/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700550
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800551Any type that has the two methods of "reader"&mdash;regardless of whatever
552other methods the type may also have&mdash;is said to <i>implement</i> the
Rob Pikee9f4fb22009-03-16 22:53:23 -0700553interface. Since "file.File" implements these methods, it implements the
Rob Pikeae05f002009-01-20 19:32:36 -0800554"reader" interface. We could tweak the "cat" subroutine to accept a "reader"
Rob Pikee9f4fb22009-03-16 22:53:23 -0700555instead of a "*file.File" and it would work just fine, but let's embellish a little
Rob Pikeae05f002009-01-20 19:32:36 -0800556first by writing a second type that implements "reader", one that wraps an
557existing "reader" and does "rot13" on the data. To do this, we just define
Rob Pikea43033a2008-09-15 11:48:37 -0700558the type and implement the methods and with no other bookkeeping,
Rob Pikeae05f002009-01-20 19:32:36 -0800559we have a second implementation of the "reader" interface.
Rob Pikea43033a2008-09-15 11:48:37 -0700560
Rob Pike9cf37c32011-07-04 16:15:14 +1000561!src progs/cat_rot13.go /type.rotate13/ /end.of.rotate13/
Rob Pikea43033a2008-09-15 11:48:37 -0700562
Rob Pike9cf37c32011-07-04 16:15:14 +1000563(The "rot13" function called in "Read" is trivial and not worth reproducing here.)
Rob Pikea43033a2008-09-15 11:48:37 -0700564
565To use the new feature, we define a flag:
566
Rob Pike9cf37c32011-07-04 16:15:14 +1000567!src progs/cat_rot13.go /rot13Flag/
Rob Pikea43033a2008-09-15 11:48:37 -0700568
Rob Pike46f482a2011-05-25 06:44:09 +1000569and use it from within a mostly unchanged "cat" function:
Rob Pikea43033a2008-09-15 11:48:37 -0700570
Rob Pike9cf37c32011-07-04 16:15:14 +1000571!src progs/cat_rot13.go /func.cat/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700572
Rob Pike46f482a2011-05-25 06:44:09 +1000573(We could also do the wrapping in "main" and leave "cat" mostly alone, except
Rob Pike40d54352009-01-09 15:16:31 -0800574for changing the type of the argument; consider that an exercise.)
Rob Pike9cf37c32011-07-04 16:15:14 +1000575The "if" at the top of "cat" sets it all up: If the "rot13" flag is true, wrap the "reader"
Rob Pikeae05f002009-01-20 19:32:36 -0800576we received into a "rotate13" and proceed. Note that the interface variables
577are values, not pointers: the argument is of type "reader", not "*reader",
Rob Pikea43033a2008-09-15 11:48:37 -0700578even though under the covers it holds a pointer to a "struct".
579
580Here it is in action:
581
Rob Pike708d7162010-07-14 13:29:12 -0700582 $ echo abcdefghijklmnopqrstuvwxyz | ./cat
Rob Pikea43033a2008-09-15 11:48:37 -0700583 abcdefghijklmnopqrstuvwxyz
Rob Pike708d7162010-07-14 13:29:12 -0700584 $ echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13
Rob Pikea43033a2008-09-15 11:48:37 -0700585 nopqrstuvwxyzabcdefghijklm
Rob Pike708d7162010-07-14 13:29:12 -0700586 $
Rob Pikea43033a2008-09-15 11:48:37 -0700587
588Fans of dependency injection may take cheer from how easily interfaces
Rob Pike81672ef2008-09-29 20:06:48 -0700589allow us to substitute the implementation of a file descriptor.
Rob Pikea43033a2008-09-15 11:48:37 -0700590
Russ Cox898714a2009-11-07 18:05:30 -0800591Interfaces are a distinctive feature of Go. An interface is implemented by a
Rob Pikea43033a2008-09-15 11:48:37 -0700592type if the type implements all the methods declared in the interface.
593This means
594that a type may implement an arbitrary number of different interfaces.
595There is no type hierarchy; things can be much more <i>ad hoc</i>,
Rob Pikee9f4fb22009-03-16 22:53:23 -0700596as we saw with "rot13". The type "file.File" implements "reader"; it could also
Rob Pikeae05f002009-01-20 19:32:36 -0800597implement a "writer", or any other interface built from its methods that
Rob Pikea43033a2008-09-15 11:48:37 -0700598fits the current situation. Consider the <i>empty interface</i>
599
Rob Pike61028772009-08-13 08:54:26 -0700600 type Empty interface {}
Rob Pikea43033a2008-09-15 11:48:37 -0700601
602<i>Every</i> type implements the empty interface, which makes it
603useful for things like containers.
604
605Sorting
606----
607
Russ Cox898714a2009-11-07 18:05:30 -0800608Interfaces provide a simple form of polymorphism. They completely
Rob Pike6aabf312009-02-04 15:13:07 -0800609separate the definition of what an object does from how it does it, allowing
610distinct implementations to be represented at different times by the
611same interface variable.
612
613As an example, consider this simple sort algorithm taken from "progs/sort.go":
Rob Pikea43033a2008-09-15 11:48:37 -0700614
Rob Pike9cf37c32011-07-04 16:15:14 +1000615!src progs/sort.go /func.Sort/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700616
Rob Pike400fa1c2009-10-13 13:05:42 -0700617The code needs only three methods, which we wrap into sort's "Interface":
Rob Pikea43033a2008-09-15 11:48:37 -0700618
Rob Pike9cf37c32011-07-04 16:15:14 +1000619!src progs/sort.go /interface/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700620
Rob Pike40d54352009-01-09 15:16:31 -0800621We can apply "Sort" to any type that implements "Len", "Less", and "Swap".
Rob Pikea43033a2008-09-15 11:48:37 -0700622The "sort" package includes the necessary methods to allow sorting of
Rob Pike40d54352009-01-09 15:16:31 -0800623arrays of integers, strings, etc.; here's the code for arrays of "int"
Rob Pikea43033a2008-09-15 11:48:37 -0700624
Rob Pike9cf37c32011-07-04 16:15:14 +1000625!src progs/sort.go /type.*IntSlice/ /Swap/
Rob Pikea43033a2008-09-15 11:48:37 -0700626
Rob Pike40d54352009-01-09 15:16:31 -0800627Here we see methods defined for non-"struct" types. You can define methods
628for any type you define and name in your package.
629
Rob Pikea43033a2008-09-15 11:48:37 -0700630And now a routine to test it out, from "progs/sortmain.go". This
631uses a function in the "sort" package, omitted here for brevity,
632to test that the result is sorted.
633
Rob Pike9cf37c32011-07-04 16:15:14 +1000634!src progs/sortmain.go /func.ints/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700635
636If we have a new type we want to be able to sort, all we need to do is
637to implement the three methods for that type, like this:
638
Rob Pike9cf37c32011-07-04 16:15:14 +1000639!src progs/sortmain.go /type.day/ /Swap/
Rob Pike40d54352009-01-09 15:16:31 -0800640
641
642Printing
Rob Pikebf983a02009-10-13 22:10:16 -0700643----
Rob Pike40d54352009-01-09 15:16:31 -0800644
645The examples of formatted printing so far have been modest. In this section
646we'll talk about how formatted I/O can be done well in Go.
647
Rob Pikebdbb3b42009-03-18 14:09:16 -0700648We've seen simple uses of the package "fmt", which
649implements "Printf", "Fprintf", and so on.
Rob Pikeae05f002009-01-20 19:32:36 -0800650Within the "fmt" package, "Printf" is declared with this signature:
Rob Pike40d54352009-01-09 15:16:31 -0800651
Rob Pikeb9055622010-06-14 12:27:22 -0700652 Printf(format string, v ...interface{}) (n int, errno os.Error)
Rob Pike40d54352009-01-09 15:16:31 -0800653
Rob Pikeb9055622010-06-14 12:27:22 -0700654The token "..." introduces a variable-length argument list that in C would
655be handled using the "stdarg.h" macros.
656In Go, variadic functions are passed a slice of the arguments of the
657specified type. In "Printf"'s case, the declaration says "...interface{}"
658so the actual type is a slice of empty interface values, "[]interface{}".
659"Printf" can examine the arguments by iterating over the slice
660and, for each element, using a type switch or the reflection library
661to interpret the value.
662It's off topic here but such run-time type analysis
663helps explain some of the nice properties of Go's "Printf",
Rob Pikeae05f002009-01-20 19:32:36 -0800664due to the ability of "Printf" to discover the type of its arguments
Rob Pike40d54352009-01-09 15:16:31 -0800665dynamically.
666
667For example, in C each format must correspond to the type of its
668argument. It's easier in many cases in Go. Instead of "%llud" you
Rob Pikeae05f002009-01-20 19:32:36 -0800669can just say "%d"; "Printf" knows the size and signedness of the
Rob Pike40d54352009-01-09 15:16:31 -0800670integer and can do the right thing for you. The snippet
671
Rob Pike9cf37c32011-07-04 16:15:14 +1000672!src progs/print.go 10 11
Rob Pike40d54352009-01-09 15:16:31 -0800673
674prints
675
676 18446744073709551615 -1
677
678In fact, if you're lazy the format "%v" will print, in a simple
679appropriate style, any value, even an array or structure. The output of
680
Rob Pike9cf37c32011-07-04 16:15:14 +1000681!src progs/print.go 14 20
Rob Pike40d54352009-01-09 15:16:31 -0800682
683is
684
685 18446744073709551615 {77 Sunset Strip} [1 2 3 4]
686
Rob Pikeae05f002009-01-20 19:32:36 -0800687You can drop the formatting altogether if you use "Print" or "Println"
688instead of "Printf". Those routines do fully automatic formatting.
689The "Print" function just prints its elements out using the equivalent
Russ Cox898714a2009-11-07 18:05:30 -0800690of "%v" while "Println" inserts spaces between arguments
Rob Pike40d54352009-01-09 15:16:31 -0800691and adds a newline. The output of each of these two lines is identical
Rob Pikeae05f002009-01-20 19:32:36 -0800692to that of the "Printf" call above.
Rob Pike40d54352009-01-09 15:16:31 -0800693
Rob Pike9cf37c32011-07-04 16:15:14 +1000694!src progs/print.go 21 22
Rob Pike40d54352009-01-09 15:16:31 -0800695
Rob Pikeae05f002009-01-20 19:32:36 -0800696If you have your own type you'd like "Printf" or "Print" to format,
Rob Pike46f482a2011-05-25 06:44:09 +1000697just give it a "String" method that returns a string. The print
Rob Pike40d54352009-01-09 15:16:31 -0800698routines will examine the value to inquire whether it implements
699the method and if so, use it rather than some other formatting.
700Here's a simple example.
701
Rob Pike9cf37c32011-07-04 16:15:14 +1000702!src progs/print_string.go 9 $
Rob Pike40d54352009-01-09 15:16:31 -0800703
Rob Pike46f482a2011-05-25 06:44:09 +1000704Since "*testType" has a "String" method, the
Rob Pike40d54352009-01-09 15:16:31 -0800705default formatter for that type will use it and produce the output
706
707 77 Sunset Strip
708
Rob Pike46f482a2011-05-25 06:44:09 +1000709Observe that the "String" method calls "Sprint" (the obvious Go
Rob Pikeae05f002009-01-20 19:32:36 -0800710variant that returns a string) to do its formatting; special formatters
711can use the "fmt" library recursively.
Rob Pike40d54352009-01-09 15:16:31 -0800712
Rob Pikeae05f002009-01-20 19:32:36 -0800713Another feature of "Printf" is that the format "%T" will print a string
Rob Pike40d54352009-01-09 15:16:31 -0800714representation of the type of a value, which can be handy when debugging
715polymorphic code.
716
717It's possible to write full custom print formats with flags and precisions
718and such, but that's getting a little off the main thread so we'll leave it
719as an exploration exercise.
720
Rob Pikeae05f002009-01-20 19:32:36 -0800721You might ask, though, how "Printf" can tell whether a type implements
Rob Pike46f482a2011-05-25 06:44:09 +1000722the "String" method. Actually what it does is ask if the value can
Rob Pike40d54352009-01-09 15:16:31 -0800723be converted to an interface variable that implements the method.
724Schematically, given a value "v", it does this:
725
726
Rob Pikedf46b332009-05-08 11:21:25 -0700727 type Stringer interface {
Rob Pike40d54352009-01-09 15:16:31 -0800728 String() string
729 }
730
Andrew Gerranda8234962010-04-28 10:50:44 +1000731 s, ok := v.(Stringer) // Test whether v implements "String()"
Rob Pike40d54352009-01-09 15:16:31 -0800732 if ok {
733 result = s.String()
734 } else {
Rob Pike83f0b712009-11-01 20:47:03 -0800735 result = defaultOutput(v)
Rob Pike40d54352009-01-09 15:16:31 -0800736 }
737
Rob Pikedf46b332009-05-08 11:21:25 -0700738The code uses a ``type assertion'' ("v.(Stringer)") to test if the value stored in
739"v" satisfies the "Stringer" interface; if it does, "s"
Rob Pike40d54352009-01-09 15:16:31 -0800740will become an interface variable implementing the method and "ok" will
741be "true". We then use the interface variable to call the method.
742(The ''comma, ok'' pattern is a Go idiom used to test the success of
743operations such as type conversion, map update, communications, and so on,
744although this is the only appearance in this tutorial.)
745If the value does not satisfy the interface, "ok" will be false.
746
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800747In this snippet the name "Stringer" follows the convention that we add ''[e]r''
Rob Pikedf46b332009-05-08 11:21:25 -0700748to interfaces describing simple method sets like this.
Rob Pike6aabf312009-02-04 15:13:07 -0800749
Rob Pikeae05f002009-01-20 19:32:36 -0800750One last wrinkle. To complete the suite, besides "Printf" etc. and "Sprintf"
751etc., there are also "Fprintf" etc. Unlike in C, "Fprintf"'s first argument is
Rob Pikedf46b332009-05-08 11:21:25 -0700752not a file. Instead, it is a variable of type "io.Writer", which is an
Rob Pike40d54352009-01-09 15:16:31 -0800753interface type defined in the "io" library:
754
Rob Pikedf46b332009-05-08 11:21:25 -0700755 type Writer interface {
Andrew Gerranda8234962010-04-28 10:50:44 +1000756 Write(p []byte) (n int, err os.Error)
Rob Pike40d54352009-01-09 15:16:31 -0800757 }
758
Rob Pikedf46b332009-05-08 11:21:25 -0700759(This interface is another conventional name, this time for "Write"; there are also
760"io.Reader", "io.ReadWriter", and so on.)
Rob Pike46f482a2011-05-25 06:44:09 +1000761Thus you can call "Fprintf" on any type that implements a standard "Write"
Rob Pike83f0b712009-11-01 20:47:03 -0800762method, not just files but also network channels, buffers, whatever
Rob Pike40d54352009-01-09 15:16:31 -0800763you want.
Rob Pikea43033a2008-09-15 11:48:37 -0700764
Rob Pikedb9002f2008-09-16 11:00:11 -0700765Prime numbers
Rob Pikea43033a2008-09-15 11:48:37 -0700766----
767
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800768Now we come to processes and communication&mdash;concurrent programming.
Rob Pikea43033a2008-09-15 11:48:37 -0700769It's a big subject so to be brief we assume some familiarity with the topic.
770
Rob Pike83f0b712009-11-01 20:47:03 -0800771A classic program in the style is a prime sieve.
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800772(The sieve of Eratosthenes is computationally more efficient than
Rob Pike83f0b712009-11-01 20:47:03 -0800773the algorithm presented here, but we are more interested in concurrency than
774algorithmics at the moment.)
Rob Pike40d54352009-01-09 15:16:31 -0800775It works by taking a stream of all the natural numbers and introducing
Rob Pikedb9002f2008-09-16 11:00:11 -0700776a sequence of filters, one for each prime, to winnow the multiples of
777that prime. At each step we have a sequence of filters of the primes
778so far, and the next number to pop out is the next prime, which triggers
779the creation of the next filter in the chain.
Rob Pikea43033a2008-09-15 11:48:37 -0700780
Rob Pikedb9002f2008-09-16 11:00:11 -0700781Here's a flow diagram; each box represents a filter element whose
782creation is triggered by the first number that flowed from the
783elements before it.
Rob Pikea43033a2008-09-15 11:48:37 -0700784
785<br>
786
Rob Pikedb9002f2008-09-16 11:00:11 -0700787&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src='sieve.gif'>
Rob Pikea43033a2008-09-15 11:48:37 -0700788
789<br>
790
791To create a stream of integers, we use a Go <i>channel</i>, which,
Rob Pikedb9002f2008-09-16 11:00:11 -0700792borrowing from CSP's descendants, represents a communications
793channel that can connect two concurrent computations.
Rob Pike40d54352009-01-09 15:16:31 -0800794In Go, channel variables are references to a run-time object that
795coordinates the communication; as with maps and slices, use
796"make" to create a new channel.
Rob Pikea43033a2008-09-15 11:48:37 -0700797
Rob Pikedb9002f2008-09-16 11:00:11 -0700798Here is the first function in "progs/sieve.go":
Rob Pikea43033a2008-09-15 11:48:37 -0700799
Rob Pike9cf37c32011-07-04 16:15:14 +1000800!src progs/sieve.go /Send/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700801
Rob Pikeae05f002009-01-20 19:32:36 -0800802The "generate" function sends the sequence 2, 3, 4, 5, ... to its
Ian Lance Taylor128f0522008-09-22 11:29:40 -0700803argument channel, "ch", using the binary communications operator "&lt;-".
Rob Pike6aabf312009-02-04 15:13:07 -0800804Channel operations block, so if there's no recipient for the value on "ch",
Rob Pikedb9002f2008-09-16 11:00:11 -0700805the send operation will wait until one becomes available.
Rob Pikea43033a2008-09-15 11:48:37 -0700806
Rob Pikeae05f002009-01-20 19:32:36 -0800807The "filter" function has three arguments: an input channel, an output
Rob Pikedb9002f2008-09-16 11:00:11 -0700808channel, and a prime number. It copies values from the input to the
Rob Pike592d2e32008-09-16 19:40:38 -0700809output, discarding anything divisible by the prime. The unary communications
Rob Pikedb9002f2008-09-16 11:00:11 -0700810operator "&lt;-" (receive) retrieves the next value on the channel.
Rob Pikea43033a2008-09-15 11:48:37 -0700811
Rob Pike9cf37c32011-07-04 16:15:14 +1000812!src progs/sieve.go /Copy.the/ /^}/
Rob Pikedb9002f2008-09-16 11:00:11 -0700813
Rob Pikedb9002f2008-09-16 11:00:11 -0700814The generator and filters execute concurrently. Go has
Rob Pikea43033a2008-09-15 11:48:37 -0700815its own model of process/threads/light-weight processes/coroutines,
Ian Lance Taylor97a55a72009-11-08 21:00:45 -0800816so to avoid notational confusion we call concurrently executing
Rob Pikea43033a2008-09-15 11:48:37 -0700817computations in Go <i>goroutines</i>. To start a goroutine,
818invoke the function, prefixing the call with the keyword "go";
Rob Pikedb9002f2008-09-16 11:00:11 -0700819this starts the function running in parallel with the current
Rob Pikea43033a2008-09-15 11:48:37 -0700820computation but in the same address space:
821
Andrew Gerranda8234962010-04-28 10:50:44 +1000822 go sum(hugeArray) // calculate sum in the background
Rob Pikea43033a2008-09-15 11:48:37 -0700823
824If you want to know when the calculation is done, pass a channel
825on which it can report back:
826
Andrew Gerranda8234962010-04-28 10:50:44 +1000827 ch := make(chan int)
828 go sum(hugeArray, ch)
Rob Pikea43033a2008-09-15 11:48:37 -0700829 // ... do something else for a while
Andrew Gerranda8234962010-04-28 10:50:44 +1000830 result := &lt;-ch // wait for, and retrieve, result
Rob Pikea43033a2008-09-15 11:48:37 -0700831
Rob Pikedb9002f2008-09-16 11:00:11 -0700832Back to our prime sieve. Here's how the sieve pipeline is stitched
833together:
Rob Pikea43033a2008-09-15 11:48:37 -0700834
Rob Pike9cf37c32011-07-04 16:15:14 +1000835!src progs/sieve.go /func.main/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700836
Rob Pike9cf37c32011-07-04 16:15:14 +1000837The first line of "main" creates the initial channel to pass to "generate", which it
Rob Pikeae05f002009-01-20 19:32:36 -0800838then starts up. As each prime pops out of the channel, a new "filter"
Rob Pikedb9002f2008-09-16 11:00:11 -0700839is added to the pipeline and <i>its</i> output becomes the new value
840of "ch".
Rob Pikea43033a2008-09-15 11:48:37 -0700841
Rob Pikedb9002f2008-09-16 11:00:11 -0700842The sieve program can be tweaked to use a pattern common
843in this style of programming. Here is a variant version
Rob Pikeae05f002009-01-20 19:32:36 -0800844of "generate", from "progs/sieve1.go":
Rob Pikea43033a2008-09-15 11:48:37 -0700845
Rob Pike9cf37c32011-07-04 16:15:14 +1000846!src progs/sieve1.go /func.generate/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700847
Rob Pikedb9002f2008-09-16 11:00:11 -0700848This version does all the setup internally. It creates the output
Russ Cox898714a2009-11-07 18:05:30 -0800849channel, launches a goroutine running a function literal, and
Rob Pikedb9002f2008-09-16 11:00:11 -0700850returns the channel to the caller. It is a factory for concurrent
851execution, starting the goroutine and returning its connection.
Rob Pike6aabf312009-02-04 15:13:07 -0800852
Rob Pike9cf37c32011-07-04 16:15:14 +1000853The function literal notation used in the "go" statement allows us to construct an
Rob Pike61028772009-08-13 08:54:26 -0700854anonymous function and invoke it on the spot. Notice that the local
855variable "ch" is available to the function literal and lives on even
856after "generate" returns.
Rob Pike6aabf312009-02-04 15:13:07 -0800857
858The same change can be made to "filter":
Rob Pikea43033a2008-09-15 11:48:37 -0700859
Rob Pike9cf37c32011-07-04 16:15:14 +1000860!src progs/sieve1.go /func.filter/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700861
Rob Pikeae05f002009-01-20 19:32:36 -0800862The "sieve" function's main loop becomes simpler and clearer as a
Rob Pikedb9002f2008-09-16 11:00:11 -0700863result, and while we're at it let's turn it into a factory too:
Rob Pikea43033a2008-09-15 11:48:37 -0700864
Rob Pike9cf37c32011-07-04 16:15:14 +1000865!src progs/sieve1.go /func.sieve/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700866
Rob Pikedb9002f2008-09-16 11:00:11 -0700867Now "main"'s interface to the prime sieve is a channel of primes:
Rob Pikea43033a2008-09-15 11:48:37 -0700868
Rob Pike9cf37c32011-07-04 16:15:14 +1000869!src progs/sieve1.go /func.main/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700870
Rob Pike68201962008-09-16 13:14:44 -0700871Multiplexing
Rob Pikedb9002f2008-09-16 11:00:11 -0700872----
Rob Pikea43033a2008-09-15 11:48:37 -0700873
Rob Pike68201962008-09-16 13:14:44 -0700874With channels, it's possible to serve multiple independent client goroutines without
Russ Cox898714a2009-11-07 18:05:30 -0800875writing an explicit multiplexer. The trick is to send the server a channel in the message,
Rob Pike68201962008-09-16 13:14:44 -0700876which it will then use to reply to the original sender.
877A realistic client-server program is a lot of code, so here is a very simple substitute
Rob Pike96777ea2009-01-30 10:18:58 -0800878to illustrate the idea. It starts by defining a "request" type, which embeds a channel
Rob Pike68201962008-09-16 13:14:44 -0700879that will be used for the reply.
Rob Pikea43033a2008-09-15 11:48:37 -0700880
Rob Pike9cf37c32011-07-04 16:15:14 +1000881!src progs/server.go /type.request/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700882
Rob Pike68201962008-09-16 13:14:44 -0700883The server will be trivial: it will do simple binary operations on integers. Here's the
884code that invokes the operation and responds to the request:
Rob Pikea43033a2008-09-15 11:48:37 -0700885
Rob Pike9cf37c32011-07-04 16:15:14 +1000886!src progs/server.go /type.binOp/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700887
Rob Pike9cf37c32011-07-04 16:15:14 +1000888The type declaration makes "binOp" represent a function taking two integers and
Rob Pike40d54352009-01-09 15:16:31 -0800889returning a third.
890
Rob Pikeae05f002009-01-20 19:32:36 -0800891The "server" routine loops forever, receiving requests and, to avoid blocking due to
Rob Pike68201962008-09-16 13:14:44 -0700892a long-running operation, starting a goroutine to do the actual work.
893
Rob Pike9cf37c32011-07-04 16:15:14 +1000894!src progs/server.go /func.server/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700895
Russ Cox898714a2009-11-07 18:05:30 -0800896We construct a server in a familiar way, starting it and returning a channel
897connected to it:
Rob Pike68201962008-09-16 13:14:44 -0700898
Rob Pike9cf37c32011-07-04 16:15:14 +1000899!src progs/server.go /func.startServer/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700900
Russ Cox898714a2009-11-07 18:05:30 -0800901Here's a simple test. It starts a server with an addition operator and sends out
902"N" requests without waiting for the replies. Only after all the requests are sent
Rob Pike68201962008-09-16 13:14:44 -0700903does it check the results.
904
Rob Pike9cf37c32011-07-04 16:15:14 +1000905!src progs/server.go /func.main/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700906
Russ Cox898714a2009-11-07 18:05:30 -0800907One annoyance with this program is that it doesn't shut down the server cleanly; when "main" returns
Rob Pike68201962008-09-16 13:14:44 -0700908there are a number of lingering goroutines blocked on communication. To solve this,
Rob Pike40d54352009-01-09 15:16:31 -0800909we can provide a second, "quit" channel to the server:
Rob Pike68201962008-09-16 13:14:44 -0700910
Rob Pike9cf37c32011-07-04 16:15:14 +1000911!src progs/server1.go /func.startServer/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700912
Rob Pikeae05f002009-01-20 19:32:36 -0800913It passes the quit channel to the "server" function, which uses it like this:
Rob Pike68201962008-09-16 13:14:44 -0700914
Rob Pike9cf37c32011-07-04 16:15:14 +1000915!src progs/server1.go /func.server/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700916
Russ Cox898714a2009-11-07 18:05:30 -0800917Inside "server", the "select" statement chooses which of the multiple communications
Rob Pike68201962008-09-16 13:14:44 -0700918listed by its cases can proceed. If all are blocked, it waits until one can proceed; if
919multiple can proceed, it chooses one at random. In this instance, the "select" allows
920the server to honor requests until it receives a quit message, at which point it
Rob Pike592d2e32008-09-16 19:40:38 -0700921returns, terminating its execution.
Rob Pike68201962008-09-16 13:14:44 -0700922
923
924All that's left is to strobe the "quit" channel
925at the end of main:
926
Rob Pike9cf37c32011-07-04 16:15:14 +1000927!src progs/server1.go /adder,.quit/
Rob Pike68201962008-09-16 13:14:44 -0700928...
Rob Pike9cf37c32011-07-04 16:15:14 +1000929!src progs/server1.go /quit....true/
Rob Pike68201962008-09-16 13:14:44 -0700930
931There's a lot more to Go programming and concurrent programming in general but this
932quick tour should give you some of the basics.