blob: e79a5f598d752b7f3c645e7a1889cd24225237a2 [file] [log] [blame]
Rob Pike66937302008-09-12 16:03:16 -07001Let's Go
Rob Pikeae4123f2008-09-10 11:46:05 -07002----
3
4Rob Pike
5
6----
Rob Pikeae05f002009-01-20 19:32:36 -08007(January 20, 2009)
Rob Pikeae4123f2008-09-10 11:46:05 -07008
9
10This document is a tutorial introduction to the basics of the Go systems programming
Rob Pike27a56172008-09-10 17:11:04 -070011language, intended for programmers familiar with C or C++. It is not a comprehensive
Rob Pike66937302008-09-12 16:03:16 -070012guide to the language; at the moment the document closest to that is the draft
13specification:
Rob Pike27a56172008-09-10 17:11:04 -070014
Ian Lance Taylor128f0522008-09-22 11:29:40 -070015 /doc/go_spec.html
Rob Pike27a56172008-09-10 17:11:04 -070016
17To check out the compiler and tools and be ready to run Go programs, see
18
19 /doc/go_setup.html
20
21The presentation proceeds through a series of modest programs to illustrate
22key features of the language. All the programs work (at time of writing) and are
23checked in at
24
25 /doc/progs
26
27Program snippets are annotated with the line number in the original file; for
28cleanliness, blank lines remain blank.
29
30Hello, World
31----
32
33Let's start in the usual way:
Rob Pikeae4123f2008-09-10 11:46:05 -070034
35--PROG progs/helloworld.go
36
Rob Pike27a56172008-09-10 17:11:04 -070037Every Go source file declares which package it's part of using a "package" statement.
38The "main" package's "main" function is where the program starts running (after
39any initialization).
Rob Pikeae4123f2008-09-10 11:46:05 -070040
Rob Pike27a56172008-09-10 17:11:04 -070041Function declarations are introduced with the "func" keyword.
Rob Pikeae4123f2008-09-10 11:46:05 -070042
Rob Pike27a56172008-09-10 17:11:04 -070043Notice that string constants can contain Unicode characters, encoded in UTF-8.
44Go is defined to accept UTF-8 input. Strings are arrays of bytes, usually used
45to store Unicode strings represented in UTF-8.
Rob Pikeae4123f2008-09-10 11:46:05 -070046
Rob Pike27a56172008-09-10 17:11:04 -070047The built-in function "print()" has been used during the early stages of
Rob Pike40d54352009-01-09 15:16:31 -080048development of the language but is not guaranteed to last. Here's a version of the
Rob Pikec7ebfed2008-09-11 10:21:02 -070049program that doesn't depend on "print()":
Rob Pike27a56172008-09-10 17:11:04 -070050
51--PROG progs/helloworld2.go
52
53This version imports the ''os'' package to acess its "Stdout" variable, of type
Rob Pike40d54352009-01-09 15:16:31 -080054"*os.FD". The "import" statement is a declaration: it names the identifier ("os")
Rob Pike68201962008-09-16 13:14:44 -070055that will be used to access members of the package imported from the file ("os"),
56found in the current directory or in a standard location.
Rob Pike40d54352009-01-09 15:16:31 -080057Given "os.Stdout" we can use its "WriteString" method to print the string.
Rob Pike27a56172008-09-10 17:11:04 -070058
59The comment convention is the same as in C++:
60
61 /* ... */
62 // ...
63
Rob Pike40d54352009-01-09 15:16:31 -080064Later we'll have much more to say about printing.
65
Rob Pike27a56172008-09-10 17:11:04 -070066Echo
67----
68
69Next up, here's a version of the Unix utility "echo(1)":
70
71--PROG progs/echo.go
72
Rob Pike40d54352009-01-09 15:16:31 -080073This program is small but it's doing a number of new things. In the last example,
Rob Pike27a56172008-09-10 17:11:04 -070074we saw "func" introducing a function. The keywords "var", "const", and "type"
75(not used yet) also introduce declarations, as does "import".
76Notice that we can group declarations of the same sort into
77parenthesized, semicolon-separated lists if we want, as on lines 3-6 and 10-13.
78But it's not necessary to do so; we could have said
79
80 const Space = " "
81 const Newline = "\n"
82
83Semicolons aren't needed here; in fact, semicolons are unnecessary after any
84top-level declaration, even though they are needed as separators <i>within</i>
85a parenthesized list of declarations.
86
Rob Pike40d54352009-01-09 15:16:31 -080087Also notice that we've dropped the explicit name from the imports; by default,
88packages are imported using the name defined by the imported package,
89which by convention is of course the file name itself. You can specify your
90own import names if you want but it's only necessary if you need to resolve
91a naming conflict.
92
93Having imported the "flag" package, line 8 creates a global variable to hold
94the value of echo's "-n" flag. The variable "n_flag" has type "*bool", pointer
95to "bool".
Rob Pike27a56172008-09-10 17:11:04 -070096
97In "main.main", we parse the arguments (line 16) and then create a local
98string variable we will use to build the output.
99
100The declaration statement has the form
101
102 var s string = "";
103
104This is the "var" keyword, followed by the name of the variable, followed by
105its type, followed by an equals sign and an initial value for the variable.
106
107Go tries to be terse, and this declaration could be shortened. Since the
108string constant is of type string, we don't have to tell the compiler that.
109We could write
110
111 var s = "";
112
113or we could go even shorter and write the idiom
114
115 s := "";
116
Rob Pike40d54352009-01-09 15:16:31 -0800117The ":=" operator is used a lot in Go to represent an initializing declaration.
118(For those who know Limbo, its ":=" construct is the same, but notice
119that Go has no colon after the name in a full "var" declaration.
120Also, for simplicity of parsing, ":=" only works inside functions, not at
121the top level.)
122There's one in the "for" clause on the next line:
Rob Pike27a56172008-09-10 17:11:04 -0700123
124--PROG progs/echo.go /for/
125
Rob Pike40d54352009-01-09 15:16:31 -0800126The "flag" package has parsed the arguments and left the non-flag arguments
Rob Pikec7ebfed2008-09-11 10:21:02 -0700127in a list that can be iterated over in the obvious way.
Rob Pike27a56172008-09-10 17:11:04 -0700128
129The Go "for" statement differs from that of C in a number of ways. First,
130it's the only looping construct; there is no "while" or "do". Second,
131there are no parentheses on the clause, but the braces on the body
Rob Pike40d54352009-01-09 15:16:31 -0800132are mandatory. The same applies to the "if" and "switch" statements.
133Later examples will show some other ways "for" can be written.
Rob Pike27a56172008-09-10 17:11:04 -0700134
Rob Pike40d54352009-01-09 15:16:31 -0800135The body of the loop builds up the string "s" by appending (using "+=")
Rob Pike27a56172008-09-10 17:11:04 -0700136the flags and separating spaces. After the loop, if the "-n" flag is not
137set, it appends a newline, and then writes the result.
138
139Notice that "main.main" is a niladic function with no return type.
140It's defined that way. Falling off the end of "main.main" means
141''success''; if you want to signal erroneous return, use
142
Rob Pikeae05f002009-01-20 19:32:36 -0800143 sys.Exit(1)
Rob Pike27a56172008-09-10 17:11:04 -0700144
145The "sys" package is built in and contains some essentials for getting
Rob Pikeae05f002009-01-20 19:32:36 -0800146started; for instance, "sys.Args" is an array used by the
147"flag" package to access the command-line arguments.
Rob Pike27a56172008-09-10 17:11:04 -0700148
Rob Pikec7ebfed2008-09-11 10:21:02 -0700149An Interlude about Types
150----
151
152Go has some familiar types such as "int" and "float", which represent
153values of the ''appropriate'' size for the machine. It also defines
154specifically-sized types such as "int8", "float64", and so on, plus
Rob Pike40d54352009-01-09 15:16:31 -0800155unsigned integer types such as "uint", "uint32", etc. These are
156distinct types; even if "int" and "int32" are both 32 bits in size,
157they are not the same type. There is also a "byte" synonym for
158"uint8", which is the element type for strings.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700159
160Speaking of "string", that's a built-in type as well. Strings are
161<i>immutable values</i> -- they are not just arrays of "byte" values.
162Once you've built a string <i>value</i>, you can't change it, although
163of course you can change a string <i>variable</i> simply by
164reassigning it. This snippet from "strings.go" is legal code:
165
166--PROG progs/strings.go /hello/ /ciao/
167
168However the following statements are illegal because they would modify
169a "string" value:
170
171 s[0] = 'x';
172 (*p)[1] = 'y';
173
174In C++ terms, Go strings are a bit like "const strings", while pointers
175to strings are analogous to "const string" references.
176
177Yes, there are pointers. However, Go simplifies their use a little;
178read on.
179
180Arrays are declared like this:
181
182 var array_of_int [10]int;
183
184Arrays, like strings, are values, but they are mutable. This differs
185from C, in which "array_of_int" would be usable as a pointer to "int".
186In Go, since arrays are values, it's meaningful (and useful) to talk
187about pointers to arrays.
188
189The size of the array is part of its type; however, one can declare
Rob Pike40d54352009-01-09 15:16:31 -0800190a <i>slice</i> variable, to which one can assign any array value
191with the same element type. Slices look a lot like arrays but have
192no explicit size ("[]" vs. "[10]") and they reference a segment of
193an underlying, often anonymous, regular array. Multiple slices
194can share data if they represent pieces of the same array;
195multiple arrays can never share data.
196
197Slices are actually much more common in Go programs than
198regular arrays; they're more flexible, have reference semantics,
199and are efficient. What they lack is the precise control of storage
200layout of a regular array; if you want to have a hundred elements
201of an array stored within your structure, you should use a regular
202array.
203
204When passing an array to a function, you almost always want
205to declare the formal parameter to be a slice. Go will automatically
206create (efficiently) a slice reference and pass that.
207
208Using slices one can write this function (from "sum.go"):
Rob Pikec7ebfed2008-09-11 10:21:02 -0700209
210--PROG progs/sum.go /sum/ /^}/
211
212and invoke it like this:
213
214--PROG progs/sum.go /1,2,3/
215
216Note how the return type ("int") is defined for "sum()" by stating it
Rob Pike40d54352009-01-09 15:16:31 -0800217after the parameter list.
218The expression "[3]int{1,2,3}" -- a type followed by a brace-bounded expression
219-- is a constructor for a value, in this case an array of 3 "ints". We pass it
220to "sum()" by (automatically) promoting it to a slice.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700221
Rob Pike40d54352009-01-09 15:16:31 -0800222If you are creating a regular array but want the compiler to count the
223elements for you, use "..." as the array size:
224
225 s := sum([...]int{1,2,3});
226
227In practice, though, unless you're meticulous about storage layout within a
228data structure, a slice - using empty brackets - is all you need:
229
230 s := sum([]int{1,2,3});
231
232There are also maps, which you can initialize like this:
Rob Pikec7ebfed2008-09-11 10:21:02 -0700233
234 m := map[string] int {"one":1 , "two":2}
235
Rob Pike40d54352009-01-09 15:16:31 -0800236The built-in function "len()", which returns number of elements,
237makes its first appearance in "sum". It works on strings, arrays,
238slices, and maps.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700239
Rob Pikec7ebfed2008-09-11 10:21:02 -0700240
Rob Pike40d54352009-01-09 15:16:31 -0800241An Interlude about Allocation
242----
Rob Pikec7ebfed2008-09-11 10:21:02 -0700243
Rob Pike40d54352009-01-09 15:16:31 -0800244Most types in Go are values. If you have an "int" or a "struct"
245or an array, assignment
246copies the contents of the object. To allocate something on the stack,
247just declare a variable. To allocate it on the heap, use "new()", which
248returns a pointer to the allocated storage.
249
250 type T struct { a, b int }
251 var t *T = new(T);
252
253or the more idiomatic
254
255 t := new(T);
256
257Some types - maps, slices, and channels (see below) have reference semantics.
258If you're holding a slice or a map and you modify its contents, other variables
259referencing the same underlying data will see the modification. If you allocate
260a reference object with "new()" you receive a pointer to an uninitialized ("nil")
261reference. Instead, for these three types you want to use "make()":
262
263 m := make(map[string] int);
264
265This statement initializes a new map ready to store entries. If you just declare
266the map, as in
267
268 var m map[string] int;
269
270it is a "nil" reference that cannot hold anything. To use the map,
271you must first initialize the reference using "make()" or by assignment to an
272existing map.
273
274Note that "new(T)" returns type "*T" while "make(T)" returns type "T".
Rob Pikec7ebfed2008-09-11 10:21:02 -0700275
276An Interlude about Constants
277----
278
279Although integers come in lots of sizes in Go, integer constants do not.
280There are no constants like "0ll" or "0x0UL". Instead, integer
Rob Pikedb9002f2008-09-16 11:00:11 -0700281constants are evaluated as ideal, large-precision values that
282can overflow only when they are assigned to an integer variable with
283too little precision to represent the value.
Rob Pikec7ebfed2008-09-11 10:21:02 -0700284
285 const hard_eight = (1 << 100) >> 97 // legal
286
287There are nuances that deserve redirection to the legalese of the
288language specification but here are some illustrative examples:
289
290 var a uint64 = 0 // a has type uint64, value 0
Rob Pike40d54352009-01-09 15:16:31 -0800291 a := uint64(0) // equivalent; use a "conversion"
Rob Pikec7ebfed2008-09-11 10:21:02 -0700292 i := 0x1234 // i gets default type: int
293 var j int = 1e6 // legal - 1000000 is representable in an int
294 x := 1.5 // a float
Rob Pike40d54352009-01-09 15:16:31 -0800295 i3div2 := 3/2 // integer division - result is 1
296 f3div2 := 3./2. // floating point division - result is 1.5
Rob Pikec7ebfed2008-09-11 10:21:02 -0700297
Rob Pike40d54352009-01-09 15:16:31 -0800298Conversions only work for simple cases such as converting "ints" of one
299sign or size to another, and between "ints" and "floats", plus a few other
300simple cases. There are no automatic numeric conversions of any kind in Go,
Rob Pikec7ebfed2008-09-11 10:21:02 -0700301other than that of making constants have concrete size and type when
302assigned to a variable.
Rob Pike66937302008-09-12 16:03:16 -0700303
304An I/O Package
305----
306
307Next we'll look at a simple package for doing file I/O with the usual
308sort of open/close/read/write interface. Here's the start of "fd.go":
309
310--PROG progs/fd.go /package/ /^}/
311
312The first line declares the name of the package -- "fd" for ''file descriptor'' --
Rob Pike40d54352009-01-09 15:16:31 -0800313and then we import two packages. The "os" package hides the differences
314between various operating systems to give a consistent view of files and
315so on; here we're only going to use its error handling utilities
316and reproduce the rudiments of its file I/O.
317
318The other item is the low-level, external "syscall" package, which provides
Rob Pike66937302008-09-12 16:03:16 -0700319a primitive interface to the underlying operating system's calls.
320
321Next is a type definition: the "type" keyword introduces a type declaration,
322in this case a data structure called "FD".
323To make things a little more interesting, our "FD" includes the name of the file
Rob Pikeae05f002009-01-20 19:32:36 -0800324that the file descriptor refers to.
Rob Pike66937302008-09-12 16:03:16 -0700325
Rob Pikeae05f002009-01-20 19:32:36 -0800326Because "FD" starts with a capital letter, the type is available outside the package,
327that is, by users of the package. In Go the rule about visibility of information is
328simple: if a name (of a top-level type, function, method, constant, variable, or of
329a structure field) is capitalized, users of the package may see it. Otherwise, the
330name and hence the thing being named is visible only inside the package in which
331it is declared. In Go, the term for publicly visible names is ''exported''.
Rob Pike66937302008-09-12 16:03:16 -0700332
Rob Pikeae05f002009-01-20 19:32:36 -0800333In the case of "FD", all its fields are lower case and so invisible to users, but we
334will soon give it some exported, upper-case methods.
335
336First, though, here is a factory to create them:
337
338--PROG progs/fd.go /newFD/ /^}/
Rob Pike66937302008-09-12 16:03:16 -0700339
340This returns a pointer to a new "FD" structure with the file descriptor and name
Rob Pike40d54352009-01-09 15:16:31 -0800341filled in. This code uses Go's notion of a ''composite literal'', analogous to
342the ones used to build maps and arrays, to construct the object. We could write
343
344 n := new(FD);
345 n.fildes = fd;
346 n.name = name;
347 return n
348
349but for simple structures like "FD" it's easier to return the address of a nonce
350composite literal, as is done here on line 17.
351
352We can use the factory to construct some familiar, exported variables of type "*FD":
Rob Pike66937302008-09-12 16:03:16 -0700353
Rob Pikeae05f002009-01-20 19:32:36 -0800354--PROG progs/fd.go /var/ /^.$/
Rob Pike66937302008-09-12 16:03:16 -0700355
Rob Pikeae05f002009-01-20 19:32:36 -0800356The "newFD" function was not exported because it's internal. The proper,
357exported factory to use is "Open":
Rob Pike66937302008-09-12 16:03:16 -0700358
359--PROG progs/fd.go /func.Open/ /^}/
360
361There are a number of new things in these few lines. First, "Open" returns
Rob Pike40d54352009-01-09 15:16:31 -0800362multiple values, an "FD" and an error (more about errors in a moment).
363We declare the
364multi-value return as a parenthesized list of declarations; syntactically
365they look just like a second parameter list. The function
Rob Pikeae05f002009-01-20 19:32:36 -0800366"syscall.Open"
Rob Pike66937302008-09-12 16:03:16 -0700367also has a multi-value return, which we can grab with the multi-variable
368declaration on line 27; it declares "r" and "e" to hold the two values,
369both of type "int64" (although you'd have to look at the "syscall" package
370to see that). Finally, line 28 returns two values: a pointer to the new "FD"
Rob Pikeae05f002009-01-20 19:32:36 -0800371and the error. If "syscall.Open" fails, the file descriptor "r" will
Rob Pike66937302008-09-12 16:03:16 -0700372be negative and "NewFD" will return "nil".
373
Rob Pike40d54352009-01-09 15:16:31 -0800374About those errors: The "os" library includes a general notion of an error
375string, maintaining a unique set of errors throughout the program. It's a
376good idea to use its facility in your own interfaces, as we do here, for
377consistent error handling throughout Go code. In "Open" we use the
378routine "os.ErrnoToError" to translate Unix's integer "errno" value into
379an error string, which will be stored in a unique instance of "*os.Error".
380
381Now that we can build "FDs", we can write methods for them. To declare
Rob Pike66937302008-09-12 16:03:16 -0700382a method of a type, we define a function to have an explicit receiver
383of that type, placed
Rob Pike40d54352009-01-09 15:16:31 -0800384in parentheses before the function name. Here are some methods for "*FD",
Rob Pike66937302008-09-12 16:03:16 -0700385each of which declares a receiver variable "fd".
386
387--PROG progs/fd.go /Close/ END
388
389There is no implicit "this" and the receiver variable must be used to access
390members of the structure. Methods are not declared within
391the "struct" declaration itself. The "struct" declaration defines only data members.
Rob Pike40d54352009-01-09 15:16:31 -0800392In fact, methods can be created for any type you name, such as an integer or
393array, not just for "structs". We'll see an an example with arrays later.
394
395These methods use the public variable "os.EINVAL" to return the ("*os.Error"
396version of the) Unix error code EINVAL. The "os" library defines a standard
397set of such error values.
Rob Pike66937302008-09-12 16:03:16 -0700398
399Finally, we can use our new package:
400
401--PROG progs/helloworld3.go
402
403and run the program:
404
405 % helloworld3
406 hello, world
407 can't open file; errno=2
408 %
409
Rob Pikea43033a2008-09-15 11:48:37 -0700410Rotting cats
411----
412
Rob Pike40d54352009-01-09 15:16:31 -0800413Building on the "fd" package, here's a simple version of the Unix utility "cat(1)",
414"progs/cat.go":
Rob Pikea43033a2008-09-15 11:48:37 -0700415
416--PROG progs/cat.go
417
418By now this should be easy to follow, but the "switch" statement introduces some
419new features. Like a "for" loop, an "if" or "switch" can include an
420initialization statement. The "switch" on line 12 uses one to create variables
421"nr" and "er" to hold the return values from "fd.Read()". (The "if" on line 19
422has the same idea.) The "switch" statement is general: it evaluates the cases
423from top to bottom looking for the first case that matches the value; the
Rob Pikedb9002f2008-09-16 11:00:11 -0700424case expressions don't need to be constants or even integers, as long as
425they all have the same type.
Rob Pikea43033a2008-09-15 11:48:37 -0700426
Rob Pike40d54352009-01-09 15:16:31 -0800427Since the "switch" value is just "true", we could leave it off -- as is also
428the situation
Rob Pikea43033a2008-09-15 11:48:37 -0700429in a "for" statement, a missing value means "true". In fact, such a "switch"
Rob Pike40d54352009-01-09 15:16:31 -0800430is a form of "if-else" chain. While we're here, it should be mentioned that in
431"switch" statements each "case" has an implicit "break".
Rob Pikea43033a2008-09-15 11:48:37 -0700432
Rob Pike40d54352009-01-09 15:16:31 -0800433Line 19 calls "Write()" by slicing the incoming buffer, which is itself a slice.
434Slices provide the standard Go way to handle I/O buffers.
Rob Pikea43033a2008-09-15 11:48:37 -0700435
436Now let's make a variant of "cat" that optionally does "rot13" on its input.
437It's easy to do by just processing the bytes, but instead we will exploit
438Go's notion of an <i>interface</i>.
439
Rob Pike40d54352009-01-09 15:16:31 -0800440The "cat()" subroutine uses only two methods of "fd": "Read()" and "String()",
Rob Pikea43033a2008-09-15 11:48:37 -0700441so let's start by defining an interface that has exactly those two methods.
442Here is code from "progs/cat_rot13.go":
443
Rob Pikeae05f002009-01-20 19:32:36 -0800444--PROG progs/cat_rot13.go /type.reader/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700445
Rob Pikeae05f002009-01-20 19:32:36 -0800446Any type that implements the two methods of "reader" -- regardless of whatever
Rob Pikea43033a2008-09-15 11:48:37 -0700447other methods the type may also contain -- is said to <i>implement</i> the
Rob Pike40d54352009-01-09 15:16:31 -0800448interface. Since "fd.FD" implements these methods, it implements the
Rob Pikeae05f002009-01-20 19:32:36 -0800449"reader" interface. We could tweak the "cat" subroutine to accept a "reader"
Rob Pike40d54352009-01-09 15:16:31 -0800450instead of a "*fd.FD" and it would work just fine, but let's embellish a little
Rob Pikeae05f002009-01-20 19:32:36 -0800451first by writing a second type that implements "reader", one that wraps an
452existing "reader" and does "rot13" on the data. To do this, we just define
Rob Pikea43033a2008-09-15 11:48:37 -0700453the type and implement the methods and with no other bookkeeping,
Rob Pikeae05f002009-01-20 19:32:36 -0800454we have a second implementation of the "reader" interface.
Rob Pikea43033a2008-09-15 11:48:37 -0700455
Rob Pikeae05f002009-01-20 19:32:36 -0800456--PROG progs/cat_rot13.go /type.rotate13/ /end.of.rotate13/
Rob Pikea43033a2008-09-15 11:48:37 -0700457
Rob Pike40d54352009-01-09 15:16:31 -0800458(The "rot13" function called on line 37 is trivial and not worth reproducing.)
Rob Pikea43033a2008-09-15 11:48:37 -0700459
460To use the new feature, we define a flag:
461
462--PROG progs/cat_rot13.go /rot13_flag/
463
464and use it from within a mostly unchanged "cat()" function:
465
466--PROG progs/cat_rot13.go /func.cat/ /^}/
467
Rob Pike81672ef2008-09-29 20:06:48 -0700468(We could also do the wrapping in "main" and leave "cat()" mostly alone, except
Rob Pike40d54352009-01-09 15:16:31 -0800469for changing the type of the argument; consider that an exercise.)
Rob Pikeae05f002009-01-20 19:32:36 -0800470Lines 51 through 53 set it all up: If the "rot13" flag is true, wrap the "reader"
471we received into a "rotate13" and proceed. Note that the interface variables
472are values, not pointers: the argument is of type "reader", not "*reader",
Rob Pikea43033a2008-09-15 11:48:37 -0700473even though under the covers it holds a pointer to a "struct".
474
475Here it is in action:
476
477<pre>
478 % echo abcdefghijklmnopqrstuvwxyz | ./cat
479 abcdefghijklmnopqrstuvwxyz
480 % echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13
481 nopqrstuvwxyzabcdefghijklm
482 %
483</pre>
484
485Fans of dependency injection may take cheer from how easily interfaces
Rob Pike81672ef2008-09-29 20:06:48 -0700486allow us to substitute the implementation of a file descriptor.
Rob Pikea43033a2008-09-15 11:48:37 -0700487
488Interfaces are a distinct feature of Go. An interface is implemented by a
489type if the type implements all the methods declared in the interface.
490This means
491that a type may implement an arbitrary number of different interfaces.
492There is no type hierarchy; things can be much more <i>ad hoc</i>,
Rob Pikeae05f002009-01-20 19:32:36 -0800493as we saw with "rot13". The type "fd.FD" implements "reader"; it could also
494implement a "writer", or any other interface built from its methods that
Rob Pikea43033a2008-09-15 11:48:37 -0700495fits the current situation. Consider the <i>empty interface</i>
496
497<pre>
498 type interface Empty {}
499</pre>
500
501<i>Every</i> type implements the empty interface, which makes it
502useful for things like containers.
503
504Sorting
505----
506
507As another example of interfaces, consider this simple sort algorithm,
508taken from "progs/sort.go":
509
510--PROG progs/sort.go /func.Sort/ /^}/
511
512The code needs only three methods, which we wrap into "SortInterface":
513
514--PROG progs/sort.go /interface/ /^}/
515
Rob Pike40d54352009-01-09 15:16:31 -0800516We can apply "Sort" to any type that implements "Len", "Less", and "Swap".
Rob Pikea43033a2008-09-15 11:48:37 -0700517The "sort" package includes the necessary methods to allow sorting of
Rob Pike40d54352009-01-09 15:16:31 -0800518arrays of integers, strings, etc.; here's the code for arrays of "int"
Rob Pikea43033a2008-09-15 11:48:37 -0700519
520--PROG progs/sort.go /type.*IntArray/ /swap/
521
Rob Pike40d54352009-01-09 15:16:31 -0800522Here we see methods defined for non-"struct" types. You can define methods
523for any type you define and name in your package.
524
Rob Pikea43033a2008-09-15 11:48:37 -0700525And now a routine to test it out, from "progs/sortmain.go". This
526uses a function in the "sort" package, omitted here for brevity,
527to test that the result is sorted.
528
529--PROG progs/sortmain.go /func.ints/ /^}/
530
531If we have a new type we want to be able to sort, all we need to do is
532to implement the three methods for that type, like this:
533
Rob Pikeae05f002009-01-20 19:32:36 -0800534--PROG progs/sortmain.go /type.day/ /Swap/
Rob Pike40d54352009-01-09 15:16:31 -0800535
536
537Printing
538---
539
540The examples of formatted printing so far have been modest. In this section
541we'll talk about how formatted I/O can be done well in Go.
542
Rob Pikeae05f002009-01-20 19:32:36 -0800543There's a package "fmt" that implements a version of "Printf" (upper case)
544that should look familiar:
Rob Pike40d54352009-01-09 15:16:31 -0800545
546--PROG progs/printf.go
547
Rob Pikeae05f002009-01-20 19:32:36 -0800548Within the "fmt" package, "Printf" is declared with this signature:
Rob Pike40d54352009-01-09 15:16:31 -0800549
Rob Pikeae05f002009-01-20 19:32:36 -0800550 Printf(format string, v ...) (n int, errno *os.Error)
Rob Pike40d54352009-01-09 15:16:31 -0800551
552That "..." represents the variadic argument list that in C would
553be handled using the "stdarg.h" macros, but in Go is passed using
554an empty interface variable ("interface {}") that is then unpacked
555using the reflection library. It's off topic here but the use of
Rob Pikeae05f002009-01-20 19:32:36 -0800556reflection helps explain some of the nice properties of Go's Printf,
557due to the ability of "Printf" to discover the type of its arguments
Rob Pike40d54352009-01-09 15:16:31 -0800558dynamically.
559
560For example, in C each format must correspond to the type of its
561argument. It's easier in many cases in Go. Instead of "%llud" you
Rob Pikeae05f002009-01-20 19:32:36 -0800562can just say "%d"; "Printf" knows the size and signedness of the
Rob Pike40d54352009-01-09 15:16:31 -0800563integer and can do the right thing for you. The snippet
564
565--PROG progs/print.go 'NR==6' 'NR==7'
566
567prints
568
569 18446744073709551615 -1
570
571In fact, if you're lazy the format "%v" will print, in a simple
572appropriate style, any value, even an array or structure. The output of
573
574--PROG progs/print.go 'NR==10' 'NR==13'
575
576is
577
578 18446744073709551615 {77 Sunset Strip} [1 2 3 4]
579
Rob Pikeae05f002009-01-20 19:32:36 -0800580You can drop the formatting altogether if you use "Print" or "Println"
581instead of "Printf". Those routines do fully automatic formatting.
582The "Print" function just prints its elements out using the equivalent
583of "%v" while "Println" automatically inserts spaces between arguments
Rob Pike40d54352009-01-09 15:16:31 -0800584and adds a newline. The output of each of these two lines is identical
Rob Pikeae05f002009-01-20 19:32:36 -0800585to that of the "Printf" call above.
Rob Pike40d54352009-01-09 15:16:31 -0800586
587--PROG progs/print.go 'NR==14' 'NR==15'
588
Rob Pikeae05f002009-01-20 19:32:36 -0800589If you have your own type you'd like "Printf" or "Print" to format,
Rob Pike40d54352009-01-09 15:16:31 -0800590just give it a "String()" method that returns a string. The print
591routines will examine the value to inquire whether it implements
592the method and if so, use it rather than some other formatting.
593Here's a simple example.
594
595--PROG progs/print_string.go 'NR==5' END
596
597Since "*T" has a "String()" method, the
598default formatter for that type will use it and produce the output
599
600 77 Sunset Strip
601
Rob Pikeae05f002009-01-20 19:32:36 -0800602Observe that the "String()" method calls "Sprint" (the obvious Go
603variant that returns a string) to do its formatting; special formatters
604can use the "fmt" library recursively.
Rob Pike40d54352009-01-09 15:16:31 -0800605
Rob Pikeae05f002009-01-20 19:32:36 -0800606Another feature of "Printf" is that the format "%T" will print a string
Rob Pike40d54352009-01-09 15:16:31 -0800607representation of the type of a value, which can be handy when debugging
608polymorphic code.
609
610It's possible to write full custom print formats with flags and precisions
611and such, but that's getting a little off the main thread so we'll leave it
612as an exploration exercise.
613
Rob Pikeae05f002009-01-20 19:32:36 -0800614You might ask, though, how "Printf" can tell whether a type implements
Rob Pike40d54352009-01-09 15:16:31 -0800615the "String()" method. Actually what it does is ask if the value can
616be converted to an interface variable that implements the method.
617Schematically, given a value "v", it does this:
618
619
620 type String interface {
621 String() string
622 }
623
624 s, ok := v.(String); // Test whether v satisfies "String"
625 if ok {
626 result = s.String()
627 } else {
628 result = default_output(v)
629 }
630
631The code tests if the value stored in
632"v" satisfies the "String" interface; if it does, "s"
633will become an interface variable implementing the method and "ok" will
634be "true". We then use the interface variable to call the method.
635(The ''comma, ok'' pattern is a Go idiom used to test the success of
636operations such as type conversion, map update, communications, and so on,
637although this is the only appearance in this tutorial.)
638If the value does not satisfy the interface, "ok" will be false.
639
Rob Pikeae05f002009-01-20 19:32:36 -0800640One last wrinkle. To complete the suite, besides "Printf" etc. and "Sprintf"
641etc., there are also "Fprintf" etc. Unlike in C, "Fprintf"'s first argument is
Rob Pike40d54352009-01-09 15:16:31 -0800642not a file. Instead, it is a variable of type "io.Write", which is an
643interface type defined in the "io" library:
644
645 export type Write interface {
646 Write(p []byte) (n int, err *os.Error);
647 }
648
Rob Pikeae05f002009-01-20 19:32:36 -0800649Thus you can call "Fprintf" on any type that implements a standard "Write()"
Rob Pike40d54352009-01-09 15:16:31 -0800650method, not just files but also network channels, buffers, rot13ers, whatever
651you want.
Rob Pikea43033a2008-09-15 11:48:37 -0700652
Rob Pikedb9002f2008-09-16 11:00:11 -0700653Prime numbers
Rob Pikea43033a2008-09-15 11:48:37 -0700654----
655
Rob Pikedb9002f2008-09-16 11:00:11 -0700656Now we come to processes and communication -- concurrent programming.
Rob Pikea43033a2008-09-15 11:48:37 -0700657It's a big subject so to be brief we assume some familiarity with the topic.
658
Rob Pikedb9002f2008-09-16 11:00:11 -0700659A classic program in the style is the prime sieve of Eratosthenes.
Rob Pike40d54352009-01-09 15:16:31 -0800660It works by taking a stream of all the natural numbers and introducing
Rob Pikedb9002f2008-09-16 11:00:11 -0700661a sequence of filters, one for each prime, to winnow the multiples of
662that prime. At each step we have a sequence of filters of the primes
663so far, and the next number to pop out is the next prime, which triggers
664the creation of the next filter in the chain.
Rob Pikea43033a2008-09-15 11:48:37 -0700665
Rob Pikedb9002f2008-09-16 11:00:11 -0700666Here's a flow diagram; each box represents a filter element whose
667creation is triggered by the first number that flowed from the
668elements before it.
Rob Pikea43033a2008-09-15 11:48:37 -0700669
670<br>
671
Rob Pikedb9002f2008-09-16 11:00:11 -0700672&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src='sieve.gif'>
Rob Pikea43033a2008-09-15 11:48:37 -0700673
674<br>
675
676To create a stream of integers, we use a Go <i>channel</i>, which,
Rob Pikedb9002f2008-09-16 11:00:11 -0700677borrowing from CSP's descendants, represents a communications
678channel that can connect two concurrent computations.
Rob Pike40d54352009-01-09 15:16:31 -0800679In Go, channel variables are references to a run-time object that
680coordinates the communication; as with maps and slices, use
681"make" to create a new channel.
Rob Pikea43033a2008-09-15 11:48:37 -0700682
Rob Pikedb9002f2008-09-16 11:00:11 -0700683Here is the first function in "progs/sieve.go":
Rob Pikea43033a2008-09-15 11:48:37 -0700684
Rob Pikedb9002f2008-09-16 11:00:11 -0700685--PROG progs/sieve.go /Send/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700686
Rob Pikeae05f002009-01-20 19:32:36 -0800687The "generate" function sends the sequence 2, 3, 4, 5, ... to its
Ian Lance Taylor128f0522008-09-22 11:29:40 -0700688argument channel, "ch", using the binary communications operator "&lt;-".
Rob Pikedb9002f2008-09-16 11:00:11 -0700689Channels block, so if there's no recipient for the the value on "ch",
690the send operation will wait until one becomes available.
Rob Pikea43033a2008-09-15 11:48:37 -0700691
Rob Pikeae05f002009-01-20 19:32:36 -0800692The "filter" function has three arguments: an input channel, an output
Rob Pikedb9002f2008-09-16 11:00:11 -0700693channel, and a prime number. It copies values from the input to the
Rob Pike592d2e32008-09-16 19:40:38 -0700694output, discarding anything divisible by the prime. The unary communications
Rob Pikedb9002f2008-09-16 11:00:11 -0700695operator "&lt;-" (receive) retrieves the next value on the channel.
Rob Pikea43033a2008-09-15 11:48:37 -0700696
Rob Pikedb9002f2008-09-16 11:00:11 -0700697--PROG progs/sieve.go /Copy/ /^}/
698
Rob Pikedb9002f2008-09-16 11:00:11 -0700699The generator and filters execute concurrently. Go has
Rob Pikea43033a2008-09-15 11:48:37 -0700700its own model of process/threads/light-weight processes/coroutines,
701so to avoid notational confusion we'll call concurrently executing
702computations in Go <i>goroutines</i>. To start a goroutine,
703invoke the function, prefixing the call with the keyword "go";
Rob Pikedb9002f2008-09-16 11:00:11 -0700704this starts the function running in parallel with the current
Rob Pikea43033a2008-09-15 11:48:37 -0700705computation but in the same address space:
706
707 go sum(huge_array); // calculate sum in the background
708
709If you want to know when the calculation is done, pass a channel
710on which it can report back:
711
Rob Pike40d54352009-01-09 15:16:31 -0800712 ch := make(chan int);
Rob Pikea43033a2008-09-15 11:48:37 -0700713 go sum(huge_array, ch);
714 // ... do something else for a while
715 result := <-ch; // wait for, and retrieve, result
716
Rob Pikedb9002f2008-09-16 11:00:11 -0700717Back to our prime sieve. Here's how the sieve pipeline is stitched
718together:
Rob Pikea43033a2008-09-15 11:48:37 -0700719
Rob Pikedb9002f2008-09-16 11:00:11 -0700720--PROG progs/sieve.go /func.main/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700721
Rob Pikeae05f002009-01-20 19:32:36 -0800722Line 23 creates the initial channel to pass to "generate", which it
723then starts up. As each prime pops out of the channel, a new "filter"
Rob Pikedb9002f2008-09-16 11:00:11 -0700724is added to the pipeline and <i>its</i> output becomes the new value
725of "ch".
Rob Pikea43033a2008-09-15 11:48:37 -0700726
Rob Pikedb9002f2008-09-16 11:00:11 -0700727The sieve program can be tweaked to use a pattern common
728in this style of programming. Here is a variant version
Rob Pikeae05f002009-01-20 19:32:36 -0800729of "generate", from "progs/sieve1.go":
Rob Pikea43033a2008-09-15 11:48:37 -0700730
Rob Pikeae05f002009-01-20 19:32:36 -0800731--PROG progs/sieve1.go /func.generate/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700732
Rob Pikedb9002f2008-09-16 11:00:11 -0700733This version does all the setup internally. It creates the output
734channel, launches a goroutine internally using a function literal, and
735returns the channel to the caller. It is a factory for concurrent
736execution, starting the goroutine and returning its connection.
737The same
Rob Pikeae05f002009-01-20 19:32:36 -0800738change can be made to "filter":
Rob Pikea43033a2008-09-15 11:48:37 -0700739
Rob Pikeae05f002009-01-20 19:32:36 -0800740--PROG progs/sieve1.go /func.filter/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700741
Rob Pikeae05f002009-01-20 19:32:36 -0800742The "sieve" function's main loop becomes simpler and clearer as a
Rob Pikedb9002f2008-09-16 11:00:11 -0700743result, and while we're at it let's turn it into a factory too:
Rob Pikea43033a2008-09-15 11:48:37 -0700744
Rob Pikeae05f002009-01-20 19:32:36 -0800745--PROG progs/sieve1.go /func.sieve/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700746
Rob Pikedb9002f2008-09-16 11:00:11 -0700747Now "main"'s interface to the prime sieve is a channel of primes:
Rob Pikea43033a2008-09-15 11:48:37 -0700748
Rob Pikedb9002f2008-09-16 11:00:11 -0700749--PROG progs/sieve1.go /func.main/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700750
Rob Pike68201962008-09-16 13:14:44 -0700751Multiplexing
Rob Pikedb9002f2008-09-16 11:00:11 -0700752----
Rob Pikea43033a2008-09-15 11:48:37 -0700753
Rob Pike68201962008-09-16 13:14:44 -0700754With channels, it's possible to serve multiple independent client goroutines without
755writing an actual multiplexer. The trick is to send the server a channel in the message,
756which it will then use to reply to the original sender.
757A realistic client-server program is a lot of code, so here is a very simple substitute
Rob Pike81672ef2008-09-29 20:06:48 -0700758to illustrate the idea. It starts by defining a "Request" type, which embeds a channel
Rob Pike68201962008-09-16 13:14:44 -0700759that will be used for the reply.
Rob Pikea43033a2008-09-15 11:48:37 -0700760
Rob Pikeae05f002009-01-20 19:32:36 -0800761--PROG progs/server.go /type.request/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700762
Rob Pike68201962008-09-16 13:14:44 -0700763The server will be trivial: it will do simple binary operations on integers. Here's the
764code that invokes the operation and responds to the request:
Rob Pikea43033a2008-09-15 11:48:37 -0700765
Rob Pikeae05f002009-01-20 19:32:36 -0800766--PROG progs/server.go /type.binOp/ /^}/
Rob Pikea43033a2008-09-15 11:48:37 -0700767
Rob Pikeae05f002009-01-20 19:32:36 -0800768Line 8 defines the name "binOp" to be a function taking two integers and
Rob Pike40d54352009-01-09 15:16:31 -0800769returning a third.
770
Rob Pikeae05f002009-01-20 19:32:36 -0800771The "server" routine loops forever, receiving requests and, to avoid blocking due to
Rob Pike68201962008-09-16 13:14:44 -0700772a long-running operation, starting a goroutine to do the actual work.
773
Rob Pikeae05f002009-01-20 19:32:36 -0800774--PROG progs/server.go /func.server/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700775
776We construct a server in a familiar way, starting it up and returning a channel to
777connect to it:
778
Rob Pikeae05f002009-01-20 19:32:36 -0800779--PROG progs/server.go /func.startServer/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700780
781Here's a simple test. It starts a server with an addition operator, and sends out
782lots of requests but doesn't wait for the reply. Only after all the requests are sent
783does it check the results.
784
785--PROG progs/server.go /func.main/ /^}/
786
787One annoyance with this program is that it doesn't exit cleanly; when "main" returns
788there are a number of lingering goroutines blocked on communication. To solve this,
Rob Pike40d54352009-01-09 15:16:31 -0800789we can provide a second, "quit" channel to the server:
Rob Pike68201962008-09-16 13:14:44 -0700790
Rob Pikeae05f002009-01-20 19:32:36 -0800791--PROG progs/server1.go /func.startServer/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700792
Rob Pikeae05f002009-01-20 19:32:36 -0800793It passes the quit channel to the "server" function, which uses it like this:
Rob Pike68201962008-09-16 13:14:44 -0700794
Rob Pikeae05f002009-01-20 19:32:36 -0800795--PROG progs/server1.go /func.server/ /^}/
Rob Pike68201962008-09-16 13:14:44 -0700796
Rob Pikeae05f002009-01-20 19:32:36 -0800797Inside "server", a "select" statement chooses which of the multiple communications
Rob Pike68201962008-09-16 13:14:44 -0700798listed by its cases can proceed. If all are blocked, it waits until one can proceed; if
799multiple can proceed, it chooses one at random. In this instance, the "select" allows
800the server to honor requests until it receives a quit message, at which point it
Rob Pike592d2e32008-09-16 19:40:38 -0700801returns, terminating its execution.
Rob Pike68201962008-09-16 13:14:44 -0700802
803
804All that's left is to strobe the "quit" channel
805at the end of main:
806
807--PROG progs/server1.go /adder,.quit/
808...
809--PROG progs/server1.go /quit....true/
810
811There's a lot more to Go programming and concurrent programming in general but this
812quick tour should give you some of the basics.