From: Rob Pike Date: Thu, 11 Sep 2008 17:21:02 +0000 (-0700) Subject: add sections about types and constants X-Git-Tag: weekly.2009-11-06~3243 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c7ebfed65567b9ac4a429bc87c48c29577a577b7;p=gostls13.git add sections about types and constants R=gri DELTA=133 (124 added, 0 deleted, 9 changed) OCL=15122 CL=15143 --- diff --git a/doc/go_tutorial.txt b/doc/go_tutorial.txt index 24ad5a6e65..e1c5456bdb 100644 --- a/doc/go_tutorial.txt +++ b/doc/go_tutorial.txt @@ -45,7 +45,7 @@ to store Unicode strings represented in UTF-8. The built-in function "print()" has been used during the early stages of development of the language but is not guaranteed to last. Here's a better version of the -program that doesn't depend on this "print()": +program that doesn't depend on "print()": --PROG progs/helloworld2.go @@ -103,20 +103,20 @@ or we could go even shorter and write the idiom s := ""; The := operator is used a lot in Go to represent an initializing declaration. -(For those who know Limbo, it's the same, except notice that there is no -colon after the name in a full "var" declaration.) -And here's one in the "for" clause on the next line: +(For those who know Limbo, its := construct is the same, but notice +that Go has no colon after the name in a full "var" declaration.) +And there's one in the "for" clause on the next line: --PROG progs/echo.go /for/ -The "Flag" package has parsed the arguments and left the non-flags in -a list that can be iterated over in the obvious way. +The "Flag" package has parsed the arguments and left the non-flag arguments +in a list that can be iterated over in the obvious way. The Go "for" statement differs from that of C in a number of ways. First, it's the only looping construct; there is no "while" or "do". Second, there are no parentheses on the clause, but the braces on the body -are mandatory. Later examples will show some other ways "for" -can be written. +are mandatory. (The same applies to the "if" statement.) Later examples +will show some other ways "for" can be written. The body of the loop builds up the string "s" by appending (using +=) the flags and separating spaces. After the loop, if the "-n" flag is not @@ -132,4 +132,104 @@ The "sys" package is built in and contains some essentials for getting started; for instance, "sys.argc()" and "sys.argv(int)" are used by the "Flag" package to access the arguments. -More to come. +An Interlude about Types +---- + +Go has some familiar types such as "int" and "float", which represent +values of the ''appropriate'' size for the machine. It also defines +specifically-sized types such as "int8", "float64", and so on, plus +unsigned integer types such as "uint", "uint32", etc. And then there +is a "byte" synonym for "uint8", which is the element type for +strings. + +Speaking of "string", that's a built-in type as well. Strings are +immutable values -- they are not just arrays of "byte" values. +Once you've built a string value, you can't change it, although +of course you can change a string variable simply by +reassigning it. This snippet from "strings.go" is legal code: + +--PROG progs/strings.go /hello/ /ciao/ + +However the following statements are illegal because they would modify +a "string" value: + + s[0] = 'x'; + (*p)[1] = 'y'; + +In C++ terms, Go strings are a bit like "const strings", while pointers +to strings are analogous to "const string" references. + +Yes, there are pointers. However, Go simplifies their use a little; +read on. + +Arrays are declared like this: + + var array_of_int [10]int; + +Arrays, like strings, are values, but they are mutable. This differs +from C, in which "array_of_int" would be usable as a pointer to "int". +In Go, since arrays are values, it's meaningful (and useful) to talk +about pointers to arrays. + +The size of the array is part of its type; however, one can declare +an open array variable, to which one can assign any array value +with the same element type. +(At the moment, only pointers to open arrays are implemented.) +Thus one can write this function (from "sum.go"): + +--PROG progs/sum.go /sum/ /^}/ + +and invoke it like this: + +--PROG progs/sum.go /1,2,3/ + +Note how the return type ("int") is defined for "sum()" by stating it +after the parameter list. Also observe that although the argument +is a pointer to an array, we can index it directly ("a[i]" not "(*a)[i]"). +The expression "[]int{1,2,3}" -- a type followed by a brace-bounded expression +-- is a constructor for a value, in this case an array of "int". We pass it +to "sum()" by taking its address. + +The built-in function "len()" appeared there too - it works on strings, +arrays, and maps, which can be built like this: + + m := map[string] int {"one":1 , "two":2} + +At least for now, maps are always pointers, so in this example +"m" has type "*map[string]int". This may change. + +You can also create a map (or anything else) with the built-in "new()" +function: + + m := new(map[string] int) + +The "new()" function always returns a pointer, an address for the object +it creates. + +An Interlude about Constants +---- + +Although integers come in lots of sizes in Go, integer constants do not. +There are no constants like "0ll" or "0x0UL". Instead, integer +constants are evaluated as ideal, arbitrary precision values that +can overflow only when they are assigned to an integer variable of +some specific size. + + const hard_eight = (1 << 100) >> 97 // legal + +There are nuances that deserve redirection to the legalese of the +language specification but here are some illustrative examples: + + var a uint64 = 0 // a has type uint64, value 0 + a := uint64(0) // equivalent; uses a "conversion" + i := 0x1234 // i gets default type: int + var j int = 1e6 // legal - 1000000 is representable in an int + x := 1.5 // a float + i3div2 = 3/2 // integer division - result is 1 + f3div2 = 3./2. // floating point division - result is 1.5 + +Conversions only work for simple cases such as converting ints of one +sign or size to another, and between ints and floats, plus a few other +simple cases. There are no automatic conversions of any kind in Go, +other than that of making constants have concrete size and type when +assigned to a variable. diff --git a/doc/progs/strings.go b/doc/progs/strings.go new file mode 100644 index 0000000000..28553c26aa --- /dev/null +++ b/doc/progs/strings.go @@ -0,0 +1,13 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +func main() { + s := "hello"; + if s[1] == 'e' { print("success") } + s = "good bye"; + var p *string = &s; + *p = "ciao"; +} diff --git a/doc/progs/sum.go b/doc/progs/sum.go new file mode 100644 index 0000000000..c8e7b10a7c --- /dev/null +++ b/doc/progs/sum.go @@ -0,0 +1,19 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +func sum(a *[]int) int { // returns an int + s := 0; + for i := 0; i < len(a); i++ { + s += a[i] + } + return s +} + + +func main() { + s := sum(&[]int{1,2,3}); // pass address of int array + print(s, "\n"); +}