From de6069d3d60eb2da7ee945c38fbe8d7249c66a6a Mon Sep 17 00:00:00 2001 From: Sonia Keys Date: Tue, 13 Aug 2013 13:52:13 -0400 Subject: Go first draft --- go.html.markdown | 423 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 423 insertions(+) create mode 100644 go.html.markdown (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown new file mode 100644 index 00000000..9888b37d --- /dev/null +++ b/go.html.markdown @@ -0,0 +1,423 @@ +--- +name: Go +category: language +language: Go +filename: learngo.go +contributors: + - ["Sonia Keys", "https://github.com/soniakeys"] +--- + +Go was created out of the need to get work done. It's not the latest trend +in computer science, but it is the newest fastest way to solve real-world +problems. + +It has familiar concepts of imperative languages with static typing. +It's fast to compile and fast to execute, it adds easy-to-understand +concurrency to leverage today's multi-core CPUs, and has features to +help with large-scale programming. + +Go comes with a great standard library and an enthusiastic community. + +```Go +// Single line comment +/* Multi- + line comment */ + +// A package clause starts every source file. +// Main is a special name declaring an executable rather than a library. +package main + +// An import declaration comes next. It declares library packages referenced +// in this file. The list must be exactly correct! Missing or unused packages +// are errors, not warnings. +import ( + "fmt" // A package in the Go standard library + "net/http" // Yes, a web server! + "strconv" // String conversions +) + +// A function definition. Main is special. It is the entry point for the +// executable program. Love it or hate it, Go uses brace brackets. +func main() { + // Println is a function that outputs a line to stdout. It can be + // called here because fmt has been imported and the function name + // "Println" is upper case. Symbols starting with an upper case letter + // are publicly visible. No other special syntax is needed to export + // something from a package. + // To call Println, qualify it with the package name, fmt. + fmt.Println("Hello world!") + + // Call another function within this package. + beyondHello() +} + +// Idiomatic Go uses camel case. Functions have parameters in parentheses. +// If there are no parameters, empty parens are still required. +func beyondHello() { + var x int // Variable declaration. Variables must be declared before use. + x = 3 // Variable assignment. + // "Short" declarations use := syntax to declare and assign, infering the + // type from the right hand side as much as possible and using some + // defaults where the rhs could be interpreted different ways. + // Idiomatic Go uses short declarations in preference to var keyword. + y := 4 + sum, prod := learnMultiple(x, y) // function returns two values + fmt.Println("sum:", sum, "prod:", prod) // simple output + learnTypes() // < y minutes, learn more! +} + +// Functions can have parameters and (multiple!) return values. +// In declarations, the symbol precedes the type, and the type does not have +// to be repeated if it is the same for multiple symbols in a row. +func learnMultiple(x, y int) (sum, prod int) { + return x + y, x * y // return two values +} + +// Some built-in types and literals. +func learnTypes() { + // Short declaration usually gives you what you want. + s := "Learn Go!" // string type + + s2 := `A "raw" string literal +can include line breaks.` // same string type + + // non-ASCII literal. Go source is UTF-8. + g := 'Σ' // rune type, an alias for uint32, holds a UTF-8 code point + + f := 3.14195 // float64, an IEEE-754 64-bit floating point number + c := 3 + 4i // complex128, represented internally with two float64s + + // You can use var syntax with an initializer if you want + // something other than the default that a short declaration gives you. + var u uint = 7 // unsigned, but implementation dependent size as with int + var pi float32 = 22. / 7 + + // Or more idiomatically, use conversion syntax with a short declaration. + n := byte('\n') // byte is an alias for uint8 + + // Arrays have size fixed at compile time. + var a4 [4]int // an array of 4 ints, initialized to all 0 + a3 := [...]int{3, 1, 5} // an array of 3 ints, initialized as shown + + // Slices have dynamic size. Arrays and slices each have advantages + // but use cases for slices are much more common. + s3 := []int{4, 5, 9} // compare to a3. no ellipsis here + s4 := make([]int, 4) // allocates slice of 4 ints, initialized to all 0 + var d2 [][]float64 // declaration only, nothing allocated here + bs := []byte("a slice") // type conversion syntax + + p, q := learnMemory() // A little side bar. + // Did you read it? This short declaration declares p and q to be of + // type pointer to int. P is now pointing into a block of of 20 ints, but + // the only one accessible is the one that p is pointing at. There is + // no p++ to get at the next one. + fmt.Println(*p, *q) // * follows a pointer. This prints two ints. + + // Maps are a dynamically growable associative array type, like the + // hash or dictionary types of some other languages. + m := map[string]int{"three": 3, "four": 4} + m["one"] = 1 + + // Unused variables are an error in Go. + // The underbar lets you "use" a variable but discard its value. + _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs + // Output of course counts as using a variable. + fmt.Println(s, c, a4, s3, d2, m) + + learnFlowControl() // back in the flow +} + +// Go is fully garbage collected. It has pointers but no pointer arithmetic. +// You can make a mistake with a nil pointer, but not by incrementing a pointer. +func learnMemory() (p, q *int) { + // Named return values p and q have type pointer to int. They are + // initialized to nil at this point. Evaluating *p or *q here would cause + // a panic--a run time error. + p = new(int) // built-in function new allocates memory. + // The allocated int is initialized to 0, p is no longer nil. + s := make([]int, 20) // allocate 20 ints as a single block of memory + s[3] = 7 // assign one of them + r := -2 // declare another local variable + return &s[3], &r // Oh my. + // The line above returns two values, yes, and both of the expressions + // are valid. & takes the address of an object. Elements of a slice are + // addressable, and so are local variables. Built-in functions new and + // make explicitly allocate memory, but local objects can be allocated + // as needed. Here memory for r will be still be referenced after the + // function returns so it will be allocated as well. The int allocated + // with new on the other hand will no longer be referenced and can be + // garbage collected as needed by the Go runtime. The memory allocated + // with make will still be referenced at that one element, and so it + // cannot be garbage collected. All 20 ints remain in memory because + // one of them is still referenced. +} + +func expensiveComputation() int { + return 1e6 +} + +func learnFlowControl() { + // If statements require brace brackets, and do not require parens. + if true { + fmt.Println("told ya") + } + // This is how we format the brace brackets. Formatting is standardized + // by the command line command "go fmt." Everybody does it. You will + // suffer endless disparaging remarks until you conform as well. + if false { + // pout + } else { + // gloat + } + // If statements can be chained of course, but it's idiomatic to use + // the handy switch statement instead. + x := 1 + switch x { + case 0: + case 1: + // cases don't "fall through" + case 2: + // unreached + } + // Like if, for doesn't use parens either. The scope of a variable + // declared in the first clause of the for statement is the statement + // and block. This x shadows the x declared above, but goes out of + // scope after the for block. + for x := 0; x < 3; x++ { // ++ is a statement + fmt.Println("iteration", x) + } + // x == 1 here. + + // For is the only loop statement in Go, but it has alternate forms. + for { // infinite loop + break // just kidding + continue // unreached + } + // The initial assignment of the for statement is handy enough that Go + // if statements can have one as well. Just like in the for statement, + // the := here means to declare and assign y first, then test y > x. + // The scope of y is limited to the if statement and block. + if y := expensiveComputation(); y > x { + x = y + } + // Functions are first class objects and function literals are handy. + // Function literals are closures. + xBig := func() bool { + return x > 100 // references x declared above switch statement. + } + fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x) + x /= 1e5 // this makes it == 10 + fmt.Println("xBig:", xBig()) // false now + + // When you need it, you'll love it. Actually Go's goto has been reformed + // a bit to avoid indeterminate states. You can't jump around variable + // declarations and you can't jump into blocks. + goto love +love: + + learnInterfaces() // Good stuff coming up! +} + +// An interface is a list of functionality that a type supports. Notably +// missing from an interface definition is any declaration of which types +// implement the interface. Types simply implement an interface or they don't. +// +// An interface can have any number of methods, but it's actually common +// for an interface to have only single method. It is idiomatic in this +// case for the single method to be named with some action, and for the +// interface name to end in "er." +// +// An interface definition is one kind of a type definition. Interface is +// a built in type. Stringer is defined here as an interface type with one +// method, String. +type Stringer interface { + String() string +} + +// Struct is another built in type. A struct aggregates "fields." +// Pair here has two fields, ints named x and y. +type pair struct { + x, y int +} + +// User defined types can have "methods." These are functions that operate +// in the context of an instance of the user defined type. The instance +// is called the "receiver" and is identified with a declaration just in front +// of the method name. The receiver here is "p." In most ways the receiver +// works just like a function parameter. +// +// This String method has the same name and return value as the String method +// of the Stringer interface. Further, String is the only method of Stringer. +// The pair type thus implements all methods of the Stringer interface and +// we say simply that pair implements Stringer. No other syntax is needed. +func (p pair) String() string { + // Sprintf is another public function in package fmt. + // Dot syntax references fields of p. + return fmt.Sprintf("(%d, %d)", p.x, p.y) +} + +func learnInterfaces() { + // Brace syntax is a "struct literal." It evaluates to an initialized + // struct. The := syntax declares and initializes p to this struct. + p := pair{3, 4} + fmt.Println(p.String()) // call String method of p, of type pair. + var i Stringer // declare i of type Stringer. + i = p // valid because pair implements Stringer + // Call String method of i, of type Stringer. Output same as above. + fmt.Println(i.String()) + // It gets more interesting now. We defined Stringer in this file, + // but the same interface happens to be defined in package fmt. + // Pair thus implements fmt.Stringer as well, and does so with no + // declaration of the fact. The definition of pair doesn't mention + // any interfaces at all, and of course the authors of fmt.Stringer + // had no idea that we were going to define pair. + // + // Functions in the fmt package know how to print some standard built in + // types, and beyond that, they see if a type implements fmt.Stringer. + // If so, they simply call the String method to ask an object for a + // printable representation of itself. + fmt.Println(p) // output same as above. Println calls String method. + fmt.Println(i) // output same as above + + learnErrorHandling() +} + +func learnErrorHandling() { + // Sometimes you just need to know if something worked or not. Go has + // a ", ok" idiom for that. Something, a map expression here, but commonly + // a function, can return a boolean value of ok or not ok as a second + // return value. + m := map[int]string{3: "three", 4: "four"} + if x, ok := m[1]; !ok { // , ok is optional but see how useful it is. + fmt.Println("no one there") + } else { + fmt.Print(x) + } + // An error value communicates not just "ok" but more about the problem. + if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value + // prints "strconv.ParseInt: parsing "non-int": invalid syntax" + fmt.Println(err) + } + // error is a built in type. It is an interface with a single method, + // defined internally as, + // + // type error interface { + // Error() string + // } + // + // The string returned by the Error method is conventionally a printable + // error message. You can define your own error types by simply adding + // an Error method. Your type then automatically implements the error + // interface. We've seen two interfaces now, fmt.Stringer and error. + + // We'll revisit interfaces a little later. Meanwhile, + learnConcurrency() +} + +// Go has concurrency support in the language definition. The element of +// concurrent execution is called a "goroutine" and is similar to a thread +// but "lighter." Goroutines are multiplexed to operating system threads +// and a running Go program can have far more goroutines than available OS +// threads. If a machine has multiple CPU cores, goroutines can run in +// parallel. +// +// Go "Channels" allow communication between goroutines in a way that is +// both powerful and easy to understand. Channel is a type in Go and objects +// of type channel are first class objects--they can be assigned to variables, +// passed around to functions, and so on. A channel works conceptually much +// like a Unix pipe. You put data in at one end and it comes out the other. +// Channel "send" and "receive" operations are goroutine-safe. No locks +// or additional synchronization is needed. + +// Inc increments a number, and sends the result on a channel. The channel +// operation makes this function useful to run concurrently with other +// goroutines. There is no special declaration though that says this function +// is concurrent. It is an ordinary function that happens to have a +// parameter of channel type. +func inc(i int, c chan int) { + c <- i + 1 // <- is the "send" operator when a channel appears on the left. +} + +// We'll use inc to increment some numbers concurrently. +func learnConcurrency() { + // Same make function used earlier to make a slice. Make allocates and + // initializes slices, maps, and channels. + c := make(chan int) + // Start three concurrent goroutines. Numbers will be incremented + // concurrently, perhaps in parallel if the machine is capable and + // properly configured. All three send to the same channel. + go inc(0, c) // go is a statement that starts a new goroutine. + go inc(10, c) + go inc(-805, c) + // Read three results from the channel and print them out. + // There is no telling in what order the results will arrive! + fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator. + + cs := make(chan string) // another channel, this one handles strings. + cc := make(chan chan string) // a channel of channels. + go func() { c <- 84 }() // start a new goroutine just to send a value + go func() { cs <- "wordy" }() // again, for cs this time + // Select has syntax like a switch statement but is doing something + // pretty different. Each case involves a channel operation. In rough + // terms, a case is selected at random out of the cases that are ready to + // communicate. If none are ready, select waits for one to become ready. + select { + case i := <-c: // the value received can be assigned to a variable + fmt.Println("it's a", i) + case <-cs: // or the value received can be discarded + fmt.Println("it's a string") + case <-cc: // empty channel, not ready for communication. + fmt.Println("didn't happen.") + } + // At this point a value was taken from either c or cs. One of the two + // goroutines started above has completed, the other will remain blocked. + + learnWebProgramming() // Go does it. You want to do it too. +} + +// A simple web server can be created with a single function from the standard +// library. ListenAndServe, in package net/http, listens at the specified +// TCP address and uses an object that knows how to serve data. "Knows how" +// means "satisfies an interface." The second parameter is of type interface, +// specifically http.Handler. http.Handler has a single method, ServeHTTP. +func learnWebProgramming() { + err := http.ListenAndServe(":8080", pair{}) + // Error returns are ubiquitous in Go. Always check error returns and + // do something with them. Often it's enough to print it out as an + // indication of what failed. Of course there are better things to do + // in production code: log it, try something else, shut everything down, + // and so on. + fmt.Println(err) +} + +// You can make any type into an http.Hander by implementing ServeHTTP. +// Lets use the pair type we defined earlier, just because we have it +// sitting around. ServeHTTP has two parameters. The request parameter +// is a struct that we'll ignore here. http.ResponseWriter is yet another +// interface! Here it is an object supplied to us with the guarantee that +// it implements its interface, which includes a method Write. +// We call this Write method to serve data. +func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("You learned Go in Y minutes!")) +} + +// And that's it for a proof-of-concept web server! If you run this program +// it will print out all the lines from the earlier parts of the lesson, then +// start this web server. To hit the web server, just point a browser at +// localhost:8080 and you'll see the message. (Then you can probably press +// ctrl-C to kill it.) +``` + +## Further Reading + +The root of all things Go is the [official Go web site](http://golang.org/). +There you can follow the tutorial, play interactively, and read lots. + +The language definition itself is highly recommended. It's easy to read +and amazingly short (as language definitions go these days.) + +On the reading list for students of Go is the source code to the standard +library. Comprehensively documented, it demonstrates the best of readable +and understandable Go, Go style, and Go idioms. Click on a function name +in the documentation and the source code comes up! + -- cgit v1.2.3 From a73d5c83c162569d0def8e481d85ece8d517b06a Mon Sep 17 00:00:00 2001 From: Sonia Keys Date: Tue, 13 Aug 2013 17:12:54 -0400 Subject: slashed comments --- go.html.markdown | 198 +++++++++++-------------------------------------------- 1 file changed, 38 insertions(+), 160 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 9888b37d..e7b35926 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -27,9 +27,7 @@ Go comes with a great standard library and an enthusiastic community. // Main is a special name declaring an executable rather than a library. package main -// An import declaration comes next. It declares library packages referenced -// in this file. The list must be exactly correct! Missing or unused packages -// are errors, not warnings. +// Import declaration declares library packages referenced in this file. import ( "fmt" // A package in the Go standard library "net/http" // Yes, a web server! @@ -39,27 +37,20 @@ import ( // A function definition. Main is special. It is the entry point for the // executable program. Love it or hate it, Go uses brace brackets. func main() { - // Println is a function that outputs a line to stdout. It can be - // called here because fmt has been imported and the function name - // "Println" is upper case. Symbols starting with an upper case letter - // are publicly visible. No other special syntax is needed to export - // something from a package. - // To call Println, qualify it with the package name, fmt. + // Println outputs a line to stdout. + // Qualify it with the package name, fmt. fmt.Println("Hello world!") // Call another function within this package. beyondHello() } -// Idiomatic Go uses camel case. Functions have parameters in parentheses. +// Functions have parameters in parentheses. // If there are no parameters, empty parens are still required. func beyondHello() { var x int // Variable declaration. Variables must be declared before use. x = 3 // Variable assignment. - // "Short" declarations use := syntax to declare and assign, infering the - // type from the right hand side as much as possible and using some - // defaults where the rhs could be interpreted different ways. - // Idiomatic Go uses short declarations in preference to var keyword. + // "Short" declarations use := to infer the type, declare, and assign. y := 4 sum, prod := learnMultiple(x, y) // function returns two values fmt.Println("sum:", sum, "prod:", prod) // simple output @@ -67,8 +58,6 @@ func beyondHello() { } // Functions can have parameters and (multiple!) return values. -// In declarations, the symbol precedes the type, and the type does not have -// to be repeated if it is the same for multiple symbols in a row. func learnMultiple(x, y int) (sum, prod int) { return x + y, x * y // return two values } @@ -87,12 +76,11 @@ can include line breaks.` // same string type f := 3.14195 // float64, an IEEE-754 64-bit floating point number c := 3 + 4i // complex128, represented internally with two float64s - // You can use var syntax with an initializer if you want - // something other than the default that a short declaration gives you. + // Var syntax with an initializers. var u uint = 7 // unsigned, but implementation dependent size as with int var pi float32 = 22. / 7 - // Or more idiomatically, use conversion syntax with a short declaration. + // Conversion syntax with a short declaration. n := byte('\n') // byte is an alias for uint8 // Arrays have size fixed at compile time. @@ -106,12 +94,8 @@ can include line breaks.` // same string type var d2 [][]float64 // declaration only, nothing allocated here bs := []byte("a slice") // type conversion syntax - p, q := learnMemory() // A little side bar. - // Did you read it? This short declaration declares p and q to be of - // type pointer to int. P is now pointing into a block of of 20 ints, but - // the only one accessible is the one that p is pointing at. There is - // no p++ to get at the next one. - fmt.Println(*p, *q) // * follows a pointer. This prints two ints. + p, q := learnMemory() // declares p, q to be type pointer to int. + fmt.Println(*p, *q) // * follows a pointer. This prints two ints. // Maps are a dynamically growable associative array type, like the // hash or dictionary types of some other languages. @@ -130,26 +114,13 @@ can include line breaks.` // same string type // Go is fully garbage collected. It has pointers but no pointer arithmetic. // You can make a mistake with a nil pointer, but not by incrementing a pointer. func learnMemory() (p, q *int) { - // Named return values p and q have type pointer to int. They are - // initialized to nil at this point. Evaluating *p or *q here would cause - // a panic--a run time error. + // Named return values p and q have type pointer to int. p = new(int) // built-in function new allocates memory. // The allocated int is initialized to 0, p is no longer nil. s := make([]int, 20) // allocate 20 ints as a single block of memory s[3] = 7 // assign one of them r := -2 // declare another local variable - return &s[3], &r // Oh my. - // The line above returns two values, yes, and both of the expressions - // are valid. & takes the address of an object. Elements of a slice are - // addressable, and so are local variables. Built-in functions new and - // make explicitly allocate memory, but local objects can be allocated - // as needed. Here memory for r will be still be referenced after the - // function returns so it will be allocated as well. The int allocated - // with new on the other hand will no longer be referenced and can be - // garbage collected as needed by the Go runtime. The memory allocated - // with make will still be referenced at that one element, and so it - // cannot be garbage collected. All 20 ints remain in memory because - // one of them is still referenced. + return &s[3], &r // & takes the address of an object. } func expensiveComputation() int { @@ -161,16 +132,13 @@ func learnFlowControl() { if true { fmt.Println("told ya") } - // This is how we format the brace brackets. Formatting is standardized - // by the command line command "go fmt." Everybody does it. You will - // suffer endless disparaging remarks until you conform as well. + // Formatting is standardized by the command line command "go fmt." if false { // pout } else { // gloat } - // If statements can be chained of course, but it's idiomatic to use - // the handy switch statement instead. + // Use switch in preference to chained if statements. x := 1 switch x { case 0: @@ -179,10 +147,7 @@ func learnFlowControl() { case 2: // unreached } - // Like if, for doesn't use parens either. The scope of a variable - // declared in the first clause of the for statement is the statement - // and block. This x shadows the x declared above, but goes out of - // scope after the for block. + // Like if, for doesn't use parens either. for x := 0; x < 3; x++ { // ++ is a statement fmt.Println("iteration", x) } @@ -193,14 +158,11 @@ func learnFlowControl() { break // just kidding continue // unreached } - // The initial assignment of the for statement is handy enough that Go - // if statements can have one as well. Just like in the for statement, - // the := here means to declare and assign y first, then test y > x. - // The scope of y is limited to the if statement and block. + // As with for, := in an if statement means to declare and assign y first, + // then test y > x. if y := expensiveComputation(); y > x { x = y } - // Functions are first class objects and function literals are handy. // Function literals are closures. xBig := func() bool { return x > 100 // references x declared above switch statement. @@ -209,48 +171,25 @@ func learnFlowControl() { x /= 1e5 // this makes it == 10 fmt.Println("xBig:", xBig()) // false now - // When you need it, you'll love it. Actually Go's goto has been reformed - // a bit to avoid indeterminate states. You can't jump around variable - // declarations and you can't jump into blocks. + // When you need it, you'll love it. goto love love: learnInterfaces() // Good stuff coming up! } -// An interface is a list of functionality that a type supports. Notably -// missing from an interface definition is any declaration of which types -// implement the interface. Types simply implement an interface or they don't. -// -// An interface can have any number of methods, but it's actually common -// for an interface to have only single method. It is idiomatic in this -// case for the single method to be named with some action, and for the -// interface name to end in "er." -// -// An interface definition is one kind of a type definition. Interface is -// a built in type. Stringer is defined here as an interface type with one -// method, String. +// Define Stringer as an interface type with one method, String. type Stringer interface { String() string } -// Struct is another built in type. A struct aggregates "fields." -// Pair here has two fields, ints named x and y. +// Define pair as a struct with two fields, ints named x and y. type pair struct { x, y int } -// User defined types can have "methods." These are functions that operate -// in the context of an instance of the user defined type. The instance -// is called the "receiver" and is identified with a declaration just in front -// of the method name. The receiver here is "p." In most ways the receiver -// works just like a function parameter. -// -// This String method has the same name and return value as the String method -// of the Stringer interface. Further, String is the only method of Stringer. -// The pair type thus implements all methods of the Stringer interface and -// we say simply that pair implements Stringer. No other syntax is needed. -func (p pair) String() string { +// Define a method on type pair. Pair now implements Stringer. +func (p pair) String() string { // p is called the "receiver" // Sprintf is another public function in package fmt. // Dot syntax references fields of p. return fmt.Sprintf("(%d, %d)", p.x, p.y) @@ -261,21 +200,13 @@ func learnInterfaces() { // struct. The := syntax declares and initializes p to this struct. p := pair{3, 4} fmt.Println(p.String()) // call String method of p, of type pair. - var i Stringer // declare i of type Stringer. + var i Stringer // declare i of interface type Stringer. i = p // valid because pair implements Stringer // Call String method of i, of type Stringer. Output same as above. fmt.Println(i.String()) - // It gets more interesting now. We defined Stringer in this file, - // but the same interface happens to be defined in package fmt. - // Pair thus implements fmt.Stringer as well, and does so with no - // declaration of the fact. The definition of pair doesn't mention - // any interfaces at all, and of course the authors of fmt.Stringer - // had no idea that we were going to define pair. - // - // Functions in the fmt package know how to print some standard built in - // types, and beyond that, they see if a type implements fmt.Stringer. - // If so, they simply call the String method to ask an object for a - // printable representation of itself. + + // Functions in the fmt package call the String method to ask an object + // for a printable representation of itself. fmt.Println(p) // output same as above. Println calls String method. fmt.Println(i) // output same as above @@ -283,57 +214,23 @@ func learnInterfaces() { } func learnErrorHandling() { - // Sometimes you just need to know if something worked or not. Go has - // a ", ok" idiom for that. Something, a map expression here, but commonly - // a function, can return a boolean value of ok or not ok as a second - // return value. + // ", ok" idiom used to tell if something worked or not. m := map[int]string{3: "three", 4: "four"} - if x, ok := m[1]; !ok { // , ok is optional but see how useful it is. + if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map. fmt.Println("no one there") } else { - fmt.Print(x) + fmt.Print(x) // x would be the value, if it were in the map. } // An error value communicates not just "ok" but more about the problem. if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value // prints "strconv.ParseInt: parsing "non-int": invalid syntax" fmt.Println(err) } - // error is a built in type. It is an interface with a single method, - // defined internally as, - // - // type error interface { - // Error() string - // } - // - // The string returned by the Error method is conventionally a printable - // error message. You can define your own error types by simply adding - // an Error method. Your type then automatically implements the error - // interface. We've seen two interfaces now, fmt.Stringer and error. - // We'll revisit interfaces a little later. Meanwhile, learnConcurrency() } -// Go has concurrency support in the language definition. The element of -// concurrent execution is called a "goroutine" and is similar to a thread -// but "lighter." Goroutines are multiplexed to operating system threads -// and a running Go program can have far more goroutines than available OS -// threads. If a machine has multiple CPU cores, goroutines can run in -// parallel. -// -// Go "Channels" allow communication between goroutines in a way that is -// both powerful and easy to understand. Channel is a type in Go and objects -// of type channel are first class objects--they can be assigned to variables, -// passed around to functions, and so on. A channel works conceptually much -// like a Unix pipe. You put data in at one end and it comes out the other. -// Channel "send" and "receive" operations are goroutine-safe. No locks -// or additional synchronization is needed. - -// Inc increments a number, and sends the result on a channel. The channel -// operation makes this function useful to run concurrently with other -// goroutines. There is no special declaration though that says this function -// is concurrent. It is an ordinary function that happens to have a -// parameter of channel type. +// c is a channel, a concurrency-safe communication object. func inc(i int, c chan int) { c <- i + 1 // <- is the "send" operator when a channel appears on the left. } @@ -357,10 +254,9 @@ func learnConcurrency() { cc := make(chan chan string) // a channel of channels. go func() { c <- 84 }() // start a new goroutine just to send a value go func() { cs <- "wordy" }() // again, for cs this time - // Select has syntax like a switch statement but is doing something - // pretty different. Each case involves a channel operation. In rough - // terms, a case is selected at random out of the cases that are ready to - // communicate. If none are ready, select waits for one to become ready. + // Select has syntax like a switch statement but each case involves + // a channel operation. It selects a case at random out of the cases + // that are ready to communicate. select { case i := <-c: // the value received can be assigned to a variable fmt.Println("it's a", i) @@ -375,37 +271,19 @@ func learnConcurrency() { learnWebProgramming() // Go does it. You want to do it too. } -// A simple web server can be created with a single function from the standard -// library. ListenAndServe, in package net/http, listens at the specified -// TCP address and uses an object that knows how to serve data. "Knows how" -// means "satisfies an interface." The second parameter is of type interface, -// specifically http.Handler. http.Handler has a single method, ServeHTTP. +// A single function from package http starts a web server. func learnWebProgramming() { + // ListenAndServe first parameter is TCP address to listen at. + // Second parameter is an interface, specifically http.Handler. err := http.ListenAndServe(":8080", pair{}) - // Error returns are ubiquitous in Go. Always check error returns and - // do something with them. Often it's enough to print it out as an - // indication of what failed. Of course there are better things to do - // in production code: log it, try something else, shut everything down, - // and so on. - fmt.Println(err) + fmt.Println(err) // don't ignore errors } -// You can make any type into an http.Hander by implementing ServeHTTP. -// Lets use the pair type we defined earlier, just because we have it -// sitting around. ServeHTTP has two parameters. The request parameter -// is a struct that we'll ignore here. http.ResponseWriter is yet another -// interface! Here it is an object supplied to us with the guarantee that -// it implements its interface, which includes a method Write. -// We call this Write method to serve data. +// Make pair an http.Handler by implementing its only method, ServeHTTP. func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Serve data with a method of http.ResponseWriter w.Write([]byte("You learned Go in Y minutes!")) } - -// And that's it for a proof-of-concept web server! If you run this program -// it will print out all the lines from the earlier parts of the lesson, then -// start this web server. To hit the web server, just point a browser at -// localhost:8080 and you'll see the message. (Then you can probably press -// ctrl-C to kill it.) ``` ## Further Reading -- cgit v1.2.3 From 4d705abd99dbe13fbdb50b5d5e74d6fe8c18f559 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 13 Aug 2013 19:59:19 -0700 Subject: Piddly things --- go.html.markdown | 354 +++++++++++++++++++++++++++---------------------------- 1 file changed, 177 insertions(+), 177 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index e7b35926..4db76a49 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -18,7 +18,7 @@ help with large-scale programming. Go comes with a great standard library and an enthusiastic community. -```Go +```go // Single line comment /* Multi- line comment */ @@ -29,260 +29,260 @@ package main // Import declaration declares library packages referenced in this file. import ( - "fmt" // A package in the Go standard library - "net/http" // Yes, a web server! - "strconv" // String conversions + "fmt" // A package in the Go standard library + "net/http" // Yes, a web server! + "strconv" // String conversions ) // A function definition. Main is special. It is the entry point for the // executable program. Love it or hate it, Go uses brace brackets. func main() { - // Println outputs a line to stdout. - // Qualify it with the package name, fmt. - fmt.Println("Hello world!") + // Println outputs a line to stdout. + // Qualify it with the package name, fmt. + fmt.Println("Hello world!") - // Call another function within this package. - beyondHello() + // Call another function within this package. + beyondHello() } // Functions have parameters in parentheses. // If there are no parameters, empty parens are still required. func beyondHello() { - var x int // Variable declaration. Variables must be declared before use. - x = 3 // Variable assignment. - // "Short" declarations use := to infer the type, declare, and assign. - y := 4 - sum, prod := learnMultiple(x, y) // function returns two values - fmt.Println("sum:", sum, "prod:", prod) // simple output - learnTypes() // < y minutes, learn more! + var x int // Variable declaration. Variables must be declared before use. + x = 3 // Variable assignment. + // "Short" declarations use := to infer the type, declare, and assign. + y := 4 + sum, prod := learnMultiple(x, y) // function returns two values + fmt.Println("sum:", sum, "prod:", prod) // simple output + learnTypes() // < y minutes, learn more! } // Functions can have parameters and (multiple!) return values. func learnMultiple(x, y int) (sum, prod int) { - return x + y, x * y // return two values + return x + y, x * y // return two values } // Some built-in types and literals. func learnTypes() { - // Short declaration usually gives you what you want. - s := "Learn Go!" // string type + // Short declaration usually gives you what you want. + s := "Learn Go!" // string type - s2 := `A "raw" string literal + s2 := `A "raw" string literal can include line breaks.` // same string type - // non-ASCII literal. Go source is UTF-8. - g := 'Σ' // rune type, an alias for uint32, holds a UTF-8 code point + // non-ASCII literal. Go source is UTF-8. + g := 'Σ' // rune type, an alias for uint32, holds a UTF-8 code point - f := 3.14195 // float64, an IEEE-754 64-bit floating point number - c := 3 + 4i // complex128, represented internally with two float64s + f := 3.14195 // float64, an IEEE-754 64-bit floating point number + c := 3 + 4i // complex128, represented internally with two float64s - // Var syntax with an initializers. - var u uint = 7 // unsigned, but implementation dependent size as with int - var pi float32 = 22. / 7 + // Var syntax with an initializers. + var u uint = 7 // unsigned, but implementation dependent size as with int + var pi float32 = 22. / 7 - // Conversion syntax with a short declaration. - n := byte('\n') // byte is an alias for uint8 + // Conversion syntax with a short declaration. + n := byte('\n') // byte is an alias for uint8 - // Arrays have size fixed at compile time. - var a4 [4]int // an array of 4 ints, initialized to all 0 - a3 := [...]int{3, 1, 5} // an array of 3 ints, initialized as shown + // Arrays have size fixed at compile time. + var a4 [4]int // an array of 4 ints, initialized to all 0 + a3 := [...]int{3, 1, 5} // an array of 3 ints, initialized as shown - // Slices have dynamic size. Arrays and slices each have advantages - // but use cases for slices are much more common. - s3 := []int{4, 5, 9} // compare to a3. no ellipsis here - s4 := make([]int, 4) // allocates slice of 4 ints, initialized to all 0 - var d2 [][]float64 // declaration only, nothing allocated here - bs := []byte("a slice") // type conversion syntax + // Slices have dynamic size. Arrays and slices each have advantages + // but use cases for slices are much more common. + s3 := []int{4, 5, 9} // compare to a3. no ellipsis here + s4 := make([]int, 4) // allocates slice of 4 ints, initialized to all 0 + var d2 [][]float64 // declaration only, nothing allocated here + bs := []byte("a slice") // type conversion syntax - p, q := learnMemory() // declares p, q to be type pointer to int. - fmt.Println(*p, *q) // * follows a pointer. This prints two ints. + p, q := learnMemory() // declares p, q to be type pointer to int. + fmt.Println(*p, *q) // * follows a pointer. This prints two ints. - // Maps are a dynamically growable associative array type, like the - // hash or dictionary types of some other languages. - m := map[string]int{"three": 3, "four": 4} - m["one"] = 1 + // Maps are a dynamically growable associative array type, like the + // hash or dictionary types of some other languages. + m := map[string]int{"three": 3, "four": 4} + m["one"] = 1 - // Unused variables are an error in Go. - // The underbar lets you "use" a variable but discard its value. - _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs - // Output of course counts as using a variable. - fmt.Println(s, c, a4, s3, d2, m) + // Unused variables are an error in Go. + // The underbar lets you "use" a variable but discard its value. + _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs + // Output of course counts as using a variable. + fmt.Println(s, c, a4, s3, d2, m) - learnFlowControl() // back in the flow + learnFlowControl() // back in the flow } // Go is fully garbage collected. It has pointers but no pointer arithmetic. // You can make a mistake with a nil pointer, but not by incrementing a pointer. func learnMemory() (p, q *int) { - // Named return values p and q have type pointer to int. - p = new(int) // built-in function new allocates memory. - // The allocated int is initialized to 0, p is no longer nil. - s := make([]int, 20) // allocate 20 ints as a single block of memory - s[3] = 7 // assign one of them - r := -2 // declare another local variable - return &s[3], &r // & takes the address of an object. + // Named return values p and q have type pointer to int. + p = new(int) // built-in function new allocates memory. + // The allocated int is initialized to 0, p is no longer nil. + s := make([]int, 20) // allocate 20 ints as a single block of memory + s[3] = 7 // assign one of them + r := -2 // declare another local variable + return &s[3], &r // & takes the address of an object. } func expensiveComputation() int { - return 1e6 + return 1e6 } func learnFlowControl() { - // If statements require brace brackets, and do not require parens. - if true { - fmt.Println("told ya") - } - // Formatting is standardized by the command line command "go fmt." - if false { - // pout - } else { - // gloat - } - // Use switch in preference to chained if statements. - x := 1 - switch x { - case 0: - case 1: - // cases don't "fall through" - case 2: - // unreached - } - // Like if, for doesn't use parens either. - for x := 0; x < 3; x++ { // ++ is a statement - fmt.Println("iteration", x) - } - // x == 1 here. - - // For is the only loop statement in Go, but it has alternate forms. - for { // infinite loop - break // just kidding - continue // unreached - } - // As with for, := in an if statement means to declare and assign y first, - // then test y > x. - if y := expensiveComputation(); y > x { - x = y - } - // Function literals are closures. - xBig := func() bool { - return x > 100 // references x declared above switch statement. - } - fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x) - x /= 1e5 // this makes it == 10 - fmt.Println("xBig:", xBig()) // false now - - // When you need it, you'll love it. - goto love + // If statements require brace brackets, and do not require parens. + if true { + fmt.Println("told ya") + } + // Formatting is standardized by the command line command "go fmt." + if false { + // pout + } else { + // gloat + } + // Use switch in preference to chained if statements. + x := 1 + switch x { + case 0: + case 1: + // cases don't "fall through" + case 2: + // unreached + } + // Like if, for doesn't use parens either. + for x := 0; x < 3; x++ { // ++ is a statement + fmt.Println("iteration", x) + } + // x == 1 here. + + // For is the only loop statement in Go, but it has alternate forms. + for { // infinite loop + break // just kidding + continue // unreached + } + // As with for, := in an if statement means to declare and assign y first, + // then test y > x. + if y := expensiveComputation(); y > x { + x = y + } + // Function literals are closures. + xBig := func() bool { + return x > 100 // references x declared above switch statement. + } + fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x) + x /= 1e5 // this makes it == 10 + fmt.Println("xBig:", xBig()) // false now + + // When you need it, you'll love it. + goto love love: - learnInterfaces() // Good stuff coming up! + learnInterfaces() // Good stuff coming up! } // Define Stringer as an interface type with one method, String. type Stringer interface { - String() string + String() string } // Define pair as a struct with two fields, ints named x and y. type pair struct { - x, y int + x, y int } // Define a method on type pair. Pair now implements Stringer. func (p pair) String() string { // p is called the "receiver" - // Sprintf is another public function in package fmt. - // Dot syntax references fields of p. - return fmt.Sprintf("(%d, %d)", p.x, p.y) + // Sprintf is another public function in package fmt. + // Dot syntax references fields of p. + return fmt.Sprintf("(%d, %d)", p.x, p.y) } func learnInterfaces() { - // Brace syntax is a "struct literal." It evaluates to an initialized - // struct. The := syntax declares and initializes p to this struct. - p := pair{3, 4} - fmt.Println(p.String()) // call String method of p, of type pair. - var i Stringer // declare i of interface type Stringer. - i = p // valid because pair implements Stringer - // Call String method of i, of type Stringer. Output same as above. - fmt.Println(i.String()) - - // Functions in the fmt package call the String method to ask an object - // for a printable representation of itself. - fmt.Println(p) // output same as above. Println calls String method. - fmt.Println(i) // output same as above - - learnErrorHandling() + // Brace syntax is a "struct literal." It evaluates to an initialized + // struct. The := syntax declares and initializes p to this struct. + p := pair{3, 4} + fmt.Println(p.String()) // call String method of p, of type pair. + var i Stringer // declare i of interface type Stringer. + i = p // valid because pair implements Stringer + // Call String method of i, of type Stringer. Output same as above. + fmt.Println(i.String()) + + // Functions in the fmt package call the String method to ask an object + // for a printable representation of itself. + fmt.Println(p) // output same as above. Println calls String method. + fmt.Println(i) // output same as above + + learnErrorHandling() } func learnErrorHandling() { - // ", ok" idiom used to tell if something worked or not. - m := map[int]string{3: "three", 4: "four"} - if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map. - fmt.Println("no one there") - } else { - fmt.Print(x) // x would be the value, if it were in the map. - } - // An error value communicates not just "ok" but more about the problem. - if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value - // prints "strconv.ParseInt: parsing "non-int": invalid syntax" - fmt.Println(err) - } - // We'll revisit interfaces a little later. Meanwhile, - learnConcurrency() + // ", ok" idiom used to tell if something worked or not. + m := map[int]string{3: "three", 4: "four"} + if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map. + fmt.Println("no one there") + } else { + fmt.Print(x) // x would be the value, if it were in the map. + } + // An error value communicates not just "ok" but more about the problem. + if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value + // prints "strconv.ParseInt: parsing "non-int": invalid syntax" + fmt.Println(err) + } + // We'll revisit interfaces a little later. Meanwhile, + learnConcurrency() } // c is a channel, a concurrency-safe communication object. func inc(i int, c chan int) { - c <- i + 1 // <- is the "send" operator when a channel appears on the left. + c <- i + 1 // <- is the "send" operator when a channel appears on the left. } // We'll use inc to increment some numbers concurrently. func learnConcurrency() { - // Same make function used earlier to make a slice. Make allocates and - // initializes slices, maps, and channels. - c := make(chan int) - // Start three concurrent goroutines. Numbers will be incremented - // concurrently, perhaps in parallel if the machine is capable and - // properly configured. All three send to the same channel. - go inc(0, c) // go is a statement that starts a new goroutine. - go inc(10, c) - go inc(-805, c) - // Read three results from the channel and print them out. - // There is no telling in what order the results will arrive! - fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator. - - cs := make(chan string) // another channel, this one handles strings. - cc := make(chan chan string) // a channel of channels. - go func() { c <- 84 }() // start a new goroutine just to send a value - go func() { cs <- "wordy" }() // again, for cs this time - // Select has syntax like a switch statement but each case involves - // a channel operation. It selects a case at random out of the cases - // that are ready to communicate. - select { - case i := <-c: // the value received can be assigned to a variable - fmt.Println("it's a", i) - case <-cs: // or the value received can be discarded - fmt.Println("it's a string") - case <-cc: // empty channel, not ready for communication. - fmt.Println("didn't happen.") - } - // At this point a value was taken from either c or cs. One of the two - // goroutines started above has completed, the other will remain blocked. - - learnWebProgramming() // Go does it. You want to do it too. + // Same make function used earlier to make a slice. Make allocates and + // initializes slices, maps, and channels. + c := make(chan int) + // Start three concurrent goroutines. Numbers will be incremented + // concurrently, perhaps in parallel if the machine is capable and + // properly configured. All three send to the same channel. + go inc(0, c) // go is a statement that starts a new goroutine. + go inc(10, c) + go inc(-805, c) + // Read three results from the channel and print them out. + // There is no telling in what order the results will arrive! + fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator. + + cs := make(chan string) // another channel, this one handles strings. + cc := make(chan chan string) // a channel of channels. + go func() { c <- 84 }() // start a new goroutine just to send a value + go func() { cs <- "wordy" }() // again, for cs this time + // Select has syntax like a switch statement but each case involves + // a channel operation. It selects a case at random out of the cases + // that are ready to communicate. + select { + case i := <-c: // the value received can be assigned to a variable + fmt.Println("it's a", i) + case <-cs: // or the value received can be discarded + fmt.Println("it's a string") + case <-cc: // empty channel, not ready for communication. + fmt.Println("didn't happen.") + } + // At this point a value was taken from either c or cs. One of the two + // goroutines started above has completed, the other will remain blocked. + + learnWebProgramming() // Go does it. You want to do it too. } // A single function from package http starts a web server. func learnWebProgramming() { - // ListenAndServe first parameter is TCP address to listen at. - // Second parameter is an interface, specifically http.Handler. - err := http.ListenAndServe(":8080", pair{}) - fmt.Println(err) // don't ignore errors + // ListenAndServe first parameter is TCP address to listen at. + // Second parameter is an interface, specifically http.Handler. + err := http.ListenAndServe(":8080", pair{}) + fmt.Println(err) // don't ignore errors } // Make pair an http.Handler by implementing its only method, ServeHTTP. func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Serve data with a method of http.ResponseWriter - w.Write([]byte("You learned Go in Y minutes!")) + // Serve data with a method of http.ResponseWriter + w.Write([]byte("You learned Go in Y minutes!")) } ``` -- cgit v1.2.3 From dde956286abf4e90f74cbbb773c57c7838d6b812 Mon Sep 17 00:00:00 2001 From: Jens Rantil Date: Wed, 4 Sep 2013 09:37:26 +0200 Subject: parens => parentheses --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 4db76a49..5d5d974b 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -46,7 +46,7 @@ func main() { } // Functions have parameters in parentheses. -// If there are no parameters, empty parens are still required. +// If there are no parameters, empty parentheses are still required. func beyondHello() { var x int // Variable declaration. Variables must be declared before use. x = 3 // Variable assignment. -- cgit v1.2.3 From abb903caba70b2813cc2194d294ee8e802dbec15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=A0uppa?= Date: Wed, 4 Sep 2013 11:30:50 +0200 Subject: chan chan string -> channel of string channels --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 4db76a49..9ffe9ed5 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -251,7 +251,7 @@ func learnConcurrency() { fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator. cs := make(chan string) // another channel, this one handles strings. - cc := make(chan chan string) // a channel of channels. + cc := make(chan chan string) // a channel of string channels. go func() { c <- 84 }() // start a new goroutine just to send a value go func() { cs <- "wordy" }() // again, for cs this time // Select has syntax like a switch statement but each case involves -- cgit v1.2.3 From 284f1ea407b576dad1b92bc59d9330c608b7adf6 Mon Sep 17 00:00:00 2001 From: NKCSS Date: Wed, 4 Sep 2013 11:52:57 +0200 Subject: Changed Print function to show the variable type This is to follow the way the string value is presented, and the format string is written (... is a ... infers a stype specification) --- go.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 4db76a49..853775c4 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -1,4 +1,4 @@ ---- +--- name: Go category: language language: Go @@ -259,7 +259,7 @@ func learnConcurrency() { // that are ready to communicate. select { case i := <-c: // the value received can be assigned to a variable - fmt.Println("it's a", i) + fmt.Printf("it's a %T", i) case <-cs: // or the value received can be discarded fmt.Println("it's a string") case <-cc: // empty channel, not ready for communication. -- cgit v1.2.3 From 078f6bbc9d3677c497a54c9286dc692a0cf815a7 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Wed, 4 Sep 2013 13:39:02 +0100 Subject: =?UTF-8?q?Corrected=20comment:=20utf-8=20=E2=86=92=20unicode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Runes hold the raw unicode code point, not utf-8. Storing utf-8 inside of a uint32 would be highly inefficient. Runes are essentially utf-32. --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 4db76a49..d7622ded 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -71,7 +71,7 @@ func learnTypes() { can include line breaks.` // same string type // non-ASCII literal. Go source is UTF-8. - g := 'Σ' // rune type, an alias for uint32, holds a UTF-8 code point + g := 'Σ' // rune type, an alias for uint32, holds a unicode code point f := 3.14195 // float64, an IEEE-754 64-bit floating point number c := 3 + 4i // complex128, represented internally with two float64s -- cgit v1.2.3 From febe5f499465edfed92aeea5e9349a660b8d5f7d Mon Sep 17 00:00:00 2001 From: Matthew Wyatt Date: Wed, 4 Sep 2013 20:46:45 -0700 Subject: Added links to source and package documentation. Also reformatted line lengths to accommdate links. --- go.html.markdown | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 3a3800dd..eec03845 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -294,8 +294,9 @@ There you can follow the tutorial, play interactively, and read lots. The language definition itself is highly recommended. It's easy to read and amazingly short (as language definitions go these days.) -On the reading list for students of Go is the source code to the standard -library. Comprehensively documented, it demonstrates the best of readable -and understandable Go, Go style, and Go idioms. Click on a function name -in the documentation and the source code comes up! +On the reading list for students of Go is the [source code to the standard +library](http://golang.org/src/pkg/). Comprehensively documented, it +demonstrates the best of readable and understandable Go, Go style, and Go +idioms. Or you can click on a function name in [the +documentation](http://golang.org/pkg/) and the source code comes up! -- cgit v1.2.3 From a933d419e07fd8af6effa89200b581e904c61679 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 8 Sep 2013 21:52:47 -0700 Subject: Some fixes --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 3a3800dd..6eb8d57d 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -1,4 +1,4 @@ ---- +--- name: Go category: language language: Go -- cgit v1.2.3 From 863194a89aa98fd446910246980e7c4ba8954cfa Mon Sep 17 00:00:00 2001 From: "C. Bess" Date: Fri, 24 Jan 2014 15:30:11 -0600 Subject: - add variadic function example --- go.html.markdown | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index ee41642a..d68ba51b 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -5,6 +5,7 @@ language: Go filename: learngo.go contributors: - ["Sonia Keys", "https://github.com/soniakeys"] + - ["Christopher Bess", "https://github.com/cbess"] --- Go was created out of the need to get work done. It's not the latest trend @@ -175,7 +176,20 @@ func learnFlowControl() { goto love love: - learnInterfaces() // Good stuff coming up! + // Good stuff coming up! + learnVariadicParams("great", "learning", "here!") + learnInterfaces() +} + +// Functions can have variadic parameters +func learnVariadicParams(myStrings ...string) { + // iterate each value of the variadic + for _, param := range myStrings { + fmt.Println("param:", param) + } + + // pass variadic value as a variadic parameter + fmt.Println("params:", fmt.Sprintln(myStrings...)) } // Define Stringer as an interface type with one method, String. -- cgit v1.2.3 From 2655b4d056d9757f5edeee571d82c86629f1f862 Mon Sep 17 00:00:00 2001 From: Jesse Johnson Date: Thu, 30 Jan 2014 18:47:55 -0500 Subject: [go/en] Fix veriadic function bug; format and clarify comments. --- go.html.markdown | 146 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 75 insertions(+), 71 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index d68ba51b..d1a0ae34 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -6,6 +6,7 @@ filename: learngo.go contributors: - ["Sonia Keys", "https://github.com/soniakeys"] - ["Christopher Bess", "https://github.com/cbess"] + - ["Jesse Johnson", "https://github.com/holocronweaver"] --- Go was created out of the need to get work done. It's not the latest trend @@ -30,9 +31,10 @@ package main // Import declaration declares library packages referenced in this file. import ( - "fmt" // A package in the Go standard library + "fmt" // A package in the Go standard library. "net/http" // Yes, a web server! - "strconv" // String conversions + "strconv" // String conversions. + m "math" // Math library with local alias m. ) // A function definition. Main is special. It is the entry point for the @@ -53,49 +55,49 @@ func beyondHello() { x = 3 // Variable assignment. // "Short" declarations use := to infer the type, declare, and assign. y := 4 - sum, prod := learnMultiple(x, y) // function returns two values - fmt.Println("sum:", sum, "prod:", prod) // simple output + sum, prod := learnMultiple(x, y) // Function returns two values. + fmt.Println("sum:", sum, "prod:", prod) // Simple output. learnTypes() // < y minutes, learn more! } // Functions can have parameters and (multiple!) return values. func learnMultiple(x, y int) (sum, prod int) { - return x + y, x * y // return two values + return x + y, x * y // Return two values. } // Some built-in types and literals. func learnTypes() { // Short declaration usually gives you what you want. - s := "Learn Go!" // string type + s := "Learn Go!" // string type. s2 := `A "raw" string literal -can include line breaks.` // same string type +can include line breaks.` // Same string type. - // non-ASCII literal. Go source is UTF-8. - g := 'Σ' // rune type, an alias for uint32, holds a unicode code point + // Non-ASCII literal. Go source is UTF-8. + g := 'Σ' // rune type, an alias for uint32, holds a unicode code point. - f := 3.14195 // float64, an IEEE-754 64-bit floating point number - c := 3 + 4i // complex128, represented internally with two float64s + f := 3.14195 // float64, an IEEE-754 64-bit floating point number. + c := 3 + 4i // complex128, represented internally with two float64's. // Var syntax with an initializers. - var u uint = 7 // unsigned, but implementation dependent size as with int + var u uint = 7 // Unsigned, but implementation dependent size as with int. var pi float32 = 22. / 7 // Conversion syntax with a short declaration. - n := byte('\n') // byte is an alias for uint8 + n := byte('\n') // byte is an alias for uint8. // Arrays have size fixed at compile time. - var a4 [4]int // an array of 4 ints, initialized to all 0 - a3 := [...]int{3, 1, 5} // an array of 3 ints, initialized as shown + var a4 [4]int // An array of 4 ints, initialized to all 0. + a3 := [...]int{3, 1, 5} // An array of 3 ints, initialized as shown. // Slices have dynamic size. Arrays and slices each have advantages // but use cases for slices are much more common. - s3 := []int{4, 5, 9} // compare to a3. no ellipsis here - s4 := make([]int, 4) // allocates slice of 4 ints, initialized to all 0 - var d2 [][]float64 // declaration only, nothing allocated here - bs := []byte("a slice") // type conversion syntax + s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here. + s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0. + var d2 [][]float64 // Declaration only, nothing allocated here. + bs := []byte("a slice") // Type conversion syntax. - p, q := learnMemory() // declares p, q to be type pointer to int. + p, q := learnMemory() // Declares p, q to be type pointer to int. fmt.Println(*p, *q) // * follows a pointer. This prints two ints. // Maps are a dynamically growable associative array type, like the @@ -109,23 +111,23 @@ can include line breaks.` // same string type // Output of course counts as using a variable. fmt.Println(s, c, a4, s3, d2, m) - learnFlowControl() // back in the flow + learnFlowControl() // Back in the flow. } // Go is fully garbage collected. It has pointers but no pointer arithmetic. // You can make a mistake with a nil pointer, but not by incrementing a pointer. func learnMemory() (p, q *int) { // Named return values p and q have type pointer to int. - p = new(int) // built-in function new allocates memory. + p = new(int) // Built-in function new allocates memory. // The allocated int is initialized to 0, p is no longer nil. - s := make([]int, 20) // allocate 20 ints as a single block of memory - s[3] = 7 // assign one of them - r := -2 // declare another local variable + s := make([]int, 20) // Allocate 20 ints as a single block of memory. + s[3] = 7 // Assign one of them. + r := -2 // Declare another local variable. return &s[3], &r // & takes the address of an object. } -func expensiveComputation() int { - return 1e6 +func expensiveComputation() float64 { + return m.Exp(10) } func learnFlowControl() { @@ -135,29 +137,31 @@ func learnFlowControl() { } // Formatting is standardized by the command line command "go fmt." if false { - // pout + // Pout. } else { - // gloat + // Gloat. } // Use switch in preference to chained if statements. - x := 1 + x := 42.0 switch x { case 0: case 1: - // cases don't "fall through" - case 2: - // unreached + case 42: + // Cases don't "fall through". + case 43: + // Unreached. } // Like if, for doesn't use parens either. - for x := 0; x < 3; x++ { // ++ is a statement + // Variables declared in for and if are local to their scope. + for x := 0; x < 3; x++ { // ++ is a statement. fmt.Println("iteration", x) } - // x == 1 here. + // x == 42 here. // For is the only loop statement in Go, but it has alternate forms. - for { // infinite loop - break // just kidding - continue // unreached + for { // Infinite loop. + break // Just kidding. + continue // Unreached. } // As with for, := in an if statement means to declare and assign y first, // then test y > x. @@ -166,30 +170,17 @@ func learnFlowControl() { } // Function literals are closures. xBig := func() bool { - return x > 100 // references x declared above switch statement. + return x > 100 // References x declared above switch statement. } - fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x) - x /= 1e5 // this makes it == 10 - fmt.Println("xBig:", xBig()) // false now + fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x). + x /= m.Exp(9) // This makes x == e. + fmt.Println("xBig:", xBig()) // false now. // When you need it, you'll love it. goto love love: - // Good stuff coming up! - learnVariadicParams("great", "learning", "here!") - learnInterfaces() -} - -// Functions can have variadic parameters -func learnVariadicParams(myStrings ...string) { - // iterate each value of the variadic - for _, param := range myStrings { - fmt.Println("param:", param) - } - - // pass variadic value as a variadic parameter - fmt.Println("params:", fmt.Sprintln(myStrings...)) + learnInterfaces() // Good stuff coming up! } // Define Stringer as an interface type with one method, String. @@ -213,16 +204,29 @@ func learnInterfaces() { // Brace syntax is a "struct literal." It evaluates to an initialized // struct. The := syntax declares and initializes p to this struct. p := pair{3, 4} - fmt.Println(p.String()) // call String method of p, of type pair. - var i Stringer // declare i of interface type Stringer. - i = p // valid because pair implements Stringer + fmt.Println(p.String()) // Call String method of p, of type pair. + var i Stringer // Declare i of interface type Stringer. + i = p // Valid because pair implements Stringer // Call String method of i, of type Stringer. Output same as above. fmt.Println(i.String()) // Functions in the fmt package call the String method to ask an object // for a printable representation of itself. - fmt.Println(p) // output same as above. Println calls String method. - fmt.Println(i) // output same as above + fmt.Println(p) // Output same as above. Println calls String method. + fmt.Println(i) // Output same as above. + + learnVariadicParams("great", "learning", "here!") +} + +// Functions can have variadic parameters. +func learnVariadicParams(myStrings ...interface{}) { + // Iterate each value of the variadic. + for _, param := range myStrings { + fmt.Println("param:", param) + } + + // Pass variadic value as a variadic parameter. + fmt.Println("params:", fmt.Sprintln(myStrings...)) learnErrorHandling() } @@ -237,7 +241,7 @@ func learnErrorHandling() { } // An error value communicates not just "ok" but more about the problem. if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value - // prints "strconv.ParseInt: parsing "non-int": invalid syntax" + // prints 'strconv.ParseInt: parsing "non-int": invalid syntax' fmt.Println(err) } // We'll revisit interfaces a little later. Meanwhile, @@ -264,19 +268,19 @@ func learnConcurrency() { // There is no telling in what order the results will arrive! fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator. - cs := make(chan string) // another channel, this one handles strings. - cc := make(chan chan string) // a channel of string channels. - go func() { c <- 84 }() // start a new goroutine just to send a value - go func() { cs <- "wordy" }() // again, for cs this time + cs := make(chan string) // Another channel, this one handles strings. + ccs := make(chan chan string) // A channel of string channels. + go func() { c <- 84 }() // Start a new goroutine just to send a value. + go func() { cs <- "wordy" }() // Again, for cs this time. // Select has syntax like a switch statement but each case involves // a channel operation. It selects a case at random out of the cases // that are ready to communicate. select { - case i := <-c: // the value received can be assigned to a variable + case i := <-c: // The value received can be assigned to a variable, fmt.Printf("it's a %T", i) - case <-cs: // or the value received can be discarded + case <-cs: // or the value received can be discarded. fmt.Println("it's a string") - case <-cc: // empty channel, not ready for communication. + case <-ccs: // Empty channel, not ready for communication. fmt.Println("didn't happen.") } // At this point a value was taken from either c or cs. One of the two @@ -287,7 +291,7 @@ func learnConcurrency() { // A single function from package http starts a web server. func learnWebProgramming() { - // ListenAndServe first parameter is TCP address to listen at. + // First parameter of ListenAndServe is TCP address to listen to. // Second parameter is an interface, specifically http.Handler. err := http.ListenAndServe(":8080", pair{}) fmt.Println(err) // don't ignore errors @@ -295,7 +299,7 @@ func learnWebProgramming() { // Make pair an http.Handler by implementing its only method, ServeHTTP. func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Serve data with a method of http.ResponseWriter + // Serve data with a method of http.ResponseWriter. w.Write([]byte("You learned Go in Y minutes!")) } ``` -- cgit v1.2.3 From ded11e254f75edfd83fc816fe609431e182f5155 Mon Sep 17 00:00:00 2001 From: Quint Guvernator Date: Sun, 2 Feb 2014 15:11:15 -0500 Subject: added defer example decided not to use file i/o as an example because external file access is rare in other tutorials. --- go.html.markdown | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index d1a0ae34..a66e8c4b 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -7,6 +7,7 @@ contributors: - ["Sonia Keys", "https://github.com/soniakeys"] - ["Christopher Bess", "https://github.com/cbess"] - ["Jesse Johnson", "https://github.com/holocronweaver"] + - ["Quint Guvernator", "https://github.com/qguv"] --- Go was created out of the need to get work done. It's not the latest trend @@ -180,9 +181,21 @@ func learnFlowControl() { goto love love: + learnDefer() // A quick detour to an important keyword. learnInterfaces() // Good stuff coming up! } + + +func learnDefer() (ok bool) { + // deferred statements are executed just before the function returns. + defer fmt.Println("deferred statements execute in reverse (LIFO) order.") + defer fmt.Println("\nThis line is being printed first because") + // defer is commonly used to close a file, so the function closing the file + // stays close to the function opening the file + return true +} + // Define Stringer as an interface type with one method, String. type Stringer interface { String() string -- cgit v1.2.3 From 07b229a425d9181810b947c5c9380f7a48fe64ba Mon Sep 17 00:00:00 2001 From: Qumeric Date: Wed, 16 Apr 2014 18:06:58 +0400 Subject: Fix Go tutorial, especially ru translation --- go.html.markdown | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index a66e8c4b..fa4c8d0b 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -171,10 +171,10 @@ func learnFlowControl() { } // Function literals are closures. xBig := func() bool { - return x > 100 // References x declared above switch statement. + return x > 10000 // References x declared above switch statement. } - fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x). - x /= m.Exp(9) // This makes x == e. + fmt.Println("xBig:", xBig()) // true (we last assigned e^10 to x). + x = 1.3e3 // This makes x == 1300 fmt.Println("xBig:", xBig()) // false now. // When you need it, you'll love it. @@ -185,13 +185,11 @@ love: learnInterfaces() // Good stuff coming up! } - - func learnDefer() (ok bool) { - // deferred statements are executed just before the function returns. + // Deferred statements are executed just before the function returns. defer fmt.Println("deferred statements execute in reverse (LIFO) order.") defer fmt.Println("\nThis line is being printed first because") - // defer is commonly used to close a file, so the function closing the file + // Defer is commonly used to close a file, so the function closing the file // stays close to the function opening the file return true } @@ -237,7 +235,7 @@ func learnVariadicParams(myStrings ...interface{}) { for _, param := range myStrings { fmt.Println("param:", param) } - + // Pass variadic value as a variadic parameter. fmt.Println("params:", fmt.Sprintln(myStrings...)) @@ -299,7 +297,7 @@ func learnConcurrency() { // At this point a value was taken from either c or cs. One of the two // goroutines started above has completed, the other will remain blocked. - learnWebProgramming() // Go does it. You want to do it too. + learnWebProgramming() // Go does it. You want to do it too. } // A single function from package http starts a web server. -- cgit v1.2.3 From 163d97c162aaaa58ef8620e8c47584baba50ebe0 Mon Sep 17 00:00:00 2001 From: Jose Donizetti Date: Sun, 11 May 2014 16:33:08 -0400 Subject: [go/en] add range index explication, and new learn source --- go.html.markdown | 3 +++ 1 file changed, 3 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index fa4c8d0b..bb6b04eb 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -8,6 +8,7 @@ contributors: - ["Christopher Bess", "https://github.com/cbess"] - ["Jesse Johnson", "https://github.com/holocronweaver"] - ["Quint Guvernator", "https://github.com/qguv"] + - ["Jose Donizetti", "https://github.com/josedonizetti"] --- Go was created out of the need to get work done. It's not the latest trend @@ -232,6 +233,7 @@ func learnInterfaces() { // Functions can have variadic parameters. func learnVariadicParams(myStrings ...interface{}) { // Iterate each value of the variadic. + // The underbar here is ignoring the index argument of the array. for _, param := range myStrings { fmt.Println("param:", param) } @@ -329,3 +331,4 @@ demonstrates the best of readable and understandable Go, Go style, and Go idioms. Or you can click on a function name in [the documentation](http://golang.org/pkg/) and the source code comes up! +Another great resource to learn Go is [Go by example](https://gobyexample.com/). -- cgit v1.2.3 From e5d8895c8e837ac8fd0b7272195d0d99afbf589b Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Sun, 22 Jun 2014 06:20:12 -0700 Subject: Should have more detail about named return values. There was not a section about named return values, and it feels like it is a valuable and important enough thing to learn early on. If nothing else, when looking at someone else's code this may be a point of confusion. --- go.html.markdown | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index bb6b04eb..2e68a25c 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -116,6 +116,16 @@ can include line breaks.` // Same string type. learnFlowControl() // Back in the flow. } +// It is possible, unlike in many other languages for functions on go +// to have named return values. +// We just have to assign a name to the type being returned in the function +// declaration line. This allows us to easily return from multiple points +// in a function as well as to only use the return keyword, without anything further. +func learnNamedReturns(x, y int) (z int) { + z = x * y + return // z is implicit here, because we named it earlier. +} + // Go is fully garbage collected. It has pointers but no pointer arithmetic. // You can make a mistake with a nil pointer, but not by incrementing a pointer. func learnMemory() (p, q *int) { -- cgit v1.2.3 From ff49deb88608785f913aa0129bab21807b397cd9 Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Sun, 22 Jun 2014 06:21:21 -0700 Subject: Fixed `on` to `in` in comment. --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 2e68a25c..0f022541 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -116,7 +116,7 @@ can include line breaks.` // Same string type. learnFlowControl() // Back in the flow. } -// It is possible, unlike in many other languages for functions on go +// It is possible, unlike in many other languages for functions in go // to have named return values. // We just have to assign a name to the type being returned in the function // declaration line. This allows us to easily return from multiple points -- cgit v1.2.3 From 94484047091a18d4b2440650382b9ecbd7840044 Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Sun, 22 Jun 2014 20:49:29 -0700 Subject: Slight language change per pull req. comment --- go.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 0f022541..0a0e6c53 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -118,9 +118,9 @@ can include line breaks.` // Same string type. // It is possible, unlike in many other languages for functions in go // to have named return values. -// We just have to assign a name to the type being returned in the function -// declaration line. This allows us to easily return from multiple points -// in a function as well as to only use the return keyword, without anything further. +// Giving a name to type being returned allows us to easily return from +// multiple points in a function as well as to only use the return keyword, +// without anything further. func learnNamedReturns(x, y int) (z int) { z = x * y return // z is implicit here, because we named it earlier. -- cgit v1.2.3 From e881ba74f302cc5cac7f21cd1e7da163ca774d78 Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Mon, 23 Jun 2014 07:31:39 -0700 Subject: Hopefully slight language improvement over orig. --- go.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 0a0e6c53..c70f96bd 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -118,9 +118,9 @@ can include line breaks.` // Same string type. // It is possible, unlike in many other languages for functions in go // to have named return values. -// Giving a name to type being returned allows us to easily return from -// multiple points in a function as well as to only use the return keyword, -// without anything further. +// Assigning a name to the type being returned in the function declaration line +// allows us to easily return from multiple points in a function as well as to +// only use the return keyword, without anything further. func learnNamedReturns(x, y int) (z int) { z = x * y return // z is implicit here, because we named it earlier. -- cgit v1.2.3 From 8b6920a70a6f52657bf59a20a4120af98e4187fe Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Sun, 29 Jun 2014 08:12:58 -0700 Subject: Learn function decorators with Go Added snippet about using closures as function decorators in Go. Also removed a few extra whitespaces. --- go.html.markdown | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index c70f96bd..a9a7de72 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -116,10 +116,10 @@ can include line breaks.` // Same string type. learnFlowControl() // Back in the flow. } -// It is possible, unlike in many other languages for functions in go +// It is possible, unlike in many other languages for functions in go // to have named return values. // Assigning a name to the type being returned in the function declaration line -// allows us to easily return from multiple points in a function as well as to +// allows us to easily return from multiple points in a function as well as to // only use the return keyword, without anything further. func learnNamedReturns(x, y int) (z int) { z = x * y @@ -196,6 +196,21 @@ love: learnInterfaces() // Good stuff coming up! } +// Decorators are common in other languages. Same can be done in Go +// with function literals that accept arguments. +func learnFunctionFactory(mystring string) func(before, after string) string { + return func(before, after string) string { + return fmt.Sprintf("%s %s %s", before, mystring, after) // new string + } +} + +// Next two are equivalent, with second being more practical +fmt.Println(learnFunctionFactory("summer")("A beautiful", "day!")) + +d := learnFunctionFactory("summer") +fmt.Println(d("A beautiful", "day!")) +fmt.Println(d("A lazy", "afternoon!")) + func learnDefer() (ok bool) { // Deferred statements are executed just before the function returns. defer fmt.Println("deferred statements execute in reverse (LIFO) order.") -- cgit v1.2.3 From 74c0a49e6d79e80b1f0a511afe3eece0cde6f43c Mon Sep 17 00:00:00 2001 From: Vincent Voyer Date: Wed, 2 Jul 2014 14:37:15 +0200 Subject: fix(go func factory): fix func factory example previous code did not run because outside main() code was done --- go.html.markdown | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index a9a7de72..980fdc66 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -192,16 +192,26 @@ func learnFlowControl() { goto love love: + learnFunctionFactory() // func returning func is fun(3)(3) learnDefer() // A quick detour to an important keyword. learnInterfaces() // Good stuff coming up! } +func learnFunctionFactory() { + // Next two are equivalent, with second being more practical + fmt.Println(sentenceFactory("summer")("A beautiful", "day!")) + + d := sentenceFactory("summer") + fmt.Println(d("A beautiful", "day!")) + fmt.Println(d("A lazy", "afternoon!")) +} + // Decorators are common in other languages. Same can be done in Go // with function literals that accept arguments. -func learnFunctionFactory(mystring string) func(before, after string) string { - return func(before, after string) string { - return fmt.Sprintf("%s %s %s", before, mystring, after) // new string - } +func sentenceFactory(mystring string) func(before, after string) string { + return func(before, after string) string { + return fmt.Sprintf("%s %s %s", before, mystring, after) // new string + } } // Next two are equivalent, with second being more practical -- cgit v1.2.3 From f2e3d99476c0b549e468e3090d0938322e8142d4 Mon Sep 17 00:00:00 2001 From: Vincent Voyer Date: Wed, 2 Jul 2014 14:55:33 +0200 Subject: feat(webserver request): add a http.Get example 1. script now exits 2. we initiate a request to the started server to prove the serverHTTP works what do you think? --- go.html.markdown | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index a9a7de72..61d7db84 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -329,17 +329,31 @@ func learnConcurrency() { // A single function from package http starts a web server. func learnWebProgramming() { + // First parameter of ListenAndServe is TCP address to listen to. // Second parameter is an interface, specifically http.Handler. - err := http.ListenAndServe(":8080", pair{}) - fmt.Println(err) // don't ignore errors + go func() { + err := http.ListenAndServe(":8080", pair{}) + fmt.Println(err) // don't ignore errors + }() + + requestServer(); } + // Make pair an http.Handler by implementing its only method, ServeHTTP. func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Serve data with a method of http.ResponseWriter. w.Write([]byte("You learned Go in Y minutes!")) } + +func requestServer() { + resp, err := http.Get("http://localhost:8080") + fmt.Println(err) + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + fmt.Printf("\nWebserver said: `%s`", string(body)) +} ``` ## Further Reading -- cgit v1.2.3 From 4c3409670319e4a450a5e0f8e4b9669e73792326 Mon Sep 17 00:00:00 2001 From: Pete Hamilton Date: Sat, 5 Jul 2014 12:03:09 +0100 Subject: Remove duplication of function factory example --- go.html.markdown | 7 ------- 1 file changed, 7 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 03227676..4ea6861b 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -214,13 +214,6 @@ func sentenceFactory(mystring string) func(before, after string) string { } } -// Next two are equivalent, with second being more practical -fmt.Println(learnFunctionFactory("summer")("A beautiful", "day!")) - -d := learnFunctionFactory("summer") -fmt.Println(d("A beautiful", "day!")) -fmt.Println(d("A lazy", "afternoon!")) - func learnDefer() (ok bool) { // Deferred statements are executed just before the function returns. defer fmt.Println("deferred statements execute in reverse (LIFO) order.") -- cgit v1.2.3 From 55e1c2adafcf0f2590633064aaf83af5ff1964af Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Wed, 9 Jul 2014 20:56:01 -0700 Subject: Go inline function literals as arguments to other functions or function literals. --- go.html.markdown | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index a9a7de72..e496117e 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -188,6 +188,15 @@ func learnFlowControl() { x = 1.3e3 // This makes x == 1300 fmt.Println("xBig:", xBig()) // false now. + // What's more is function literals may be defined and called inline, + // acting as an argument to function, as long as: + // a) function literal is called immediately (), + // b) result type matches expected type of argument. + fmt.Println("Add + double two numbers: ", + func(a, b int) int { + return (a + b) * 2 + }(10, 2)) // Called with args (10, 2) + // When you need it, you'll love it. goto love love: -- cgit v1.2.3 From 174f0baa14421834e181f37bd969d7f015a02adc Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Thu, 10 Jul 2014 09:22:47 -0700 Subject: Small change to inline literal functions comments. --- go.html.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index e496117e..a5ea5859 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -195,7 +195,8 @@ func learnFlowControl() { fmt.Println("Add + double two numbers: ", func(a, b int) int { return (a + b) * 2 - }(10, 2)) // Called with args (10, 2) + }(10, 2)) // Called with args 10 and 2 + // Add + double two numbers: 24 // When you need it, you'll love it. goto love -- cgit v1.2.3 From 7cddab2925260946c61eac60cc62764017a8e8af Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Thu, 10 Jul 2014 09:25:48 -0700 Subject: Forgot to add `=>` to comment line. --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index a5ea5859..88e2c8da 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -196,7 +196,7 @@ func learnFlowControl() { func(a, b int) int { return (a + b) * 2 }(10, 2)) // Called with args 10 and 2 - // Add + double two numbers: 24 + // => Add + double two numbers: 24 // When you need it, you'll love it. goto love -- cgit v1.2.3 From c022e2e857ceca9914f0b6ff8d4d2f9e60a729cd Mon Sep 17 00:00:00 2001 From: Hey Alexej Date: Wed, 16 Jul 2014 05:28:50 +0700 Subject: fix import of io/ioutil, run gofmt generated/downloaded file doesn't work with "go run". it's missing ioutil. ran gofmt which uses tabs (width=8) for formatting. longest line is 85 characters now. removed whitespace. --- go.html.markdown | 449 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 225 insertions(+), 224 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 0ecc6120..a1be08af 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -9,6 +9,7 @@ contributors: - ["Jesse Johnson", "https://github.com/holocronweaver"] - ["Quint Guvernator", "https://github.com/qguv"] - ["Jose Donizetti", "https://github.com/josedonizetti"] + - ["Alexej Friesen", "https://github.com/heyalexej"] --- Go was created out of the need to get work done. It's not the latest trend @@ -33,87 +34,88 @@ package main // Import declaration declares library packages referenced in this file. import ( - "fmt" // A package in the Go standard library. - "net/http" // Yes, a web server! - "strconv" // String conversions. - m "math" // Math library with local alias m. + "fmt" // A package in the Go standard library. + "io/ioutil" // Implements some I/O utility functions. + m "math" // Math library with local alias m. + "net/http" // Yes, a web server! + "strconv" // String conversions. ) // A function definition. Main is special. It is the entry point for the // executable program. Love it or hate it, Go uses brace brackets. func main() { - // Println outputs a line to stdout. - // Qualify it with the package name, fmt. - fmt.Println("Hello world!") + // Println outputs a line to stdout. + // Qualify it with the package name, fmt. + fmt.Println("Hello world!") - // Call another function within this package. - beyondHello() + // Call another function within this package. + beyondHello() } // Functions have parameters in parentheses. // If there are no parameters, empty parentheses are still required. func beyondHello() { - var x int // Variable declaration. Variables must be declared before use. - x = 3 // Variable assignment. - // "Short" declarations use := to infer the type, declare, and assign. - y := 4 - sum, prod := learnMultiple(x, y) // Function returns two values. - fmt.Println("sum:", sum, "prod:", prod) // Simple output. - learnTypes() // < y minutes, learn more! + var x int // Variable declaration. Variables must be declared before use. + x = 3 // Variable assignment. + // "Short" declarations use := to infer the type, declare, and assign. + y := 4 + sum, prod := learnMultiple(x, y) // Function returns two values. + fmt.Println("sum:", sum, "prod:", prod) // Simple output. + learnTypes() // < y minutes, learn more! } // Functions can have parameters and (multiple!) return values. func learnMultiple(x, y int) (sum, prod int) { - return x + y, x * y // Return two values. + return x + y, x * y // Return two values. } // Some built-in types and literals. func learnTypes() { - // Short declaration usually gives you what you want. - s := "Learn Go!" // string type. + // Short declaration usually gives you what you want. + s := "Learn Go!" // string type. - s2 := `A "raw" string literal + s2 := `A "raw" string literal can include line breaks.` // Same string type. - // Non-ASCII literal. Go source is UTF-8. - g := 'Σ' // rune type, an alias for uint32, holds a unicode code point. + // Non-ASCII literal. Go source is UTF-8. + g := 'Σ' // rune type, an alias for uint32, holds a unicode code point. - f := 3.14195 // float64, an IEEE-754 64-bit floating point number. - c := 3 + 4i // complex128, represented internally with two float64's. + f := 3.14195 // float64, an IEEE-754 64-bit floating point number. + c := 3 + 4i // complex128, represented internally with two float64's. - // Var syntax with an initializers. - var u uint = 7 // Unsigned, but implementation dependent size as with int. - var pi float32 = 22. / 7 + // Var syntax with an initializers. + var u uint = 7 // Unsigned, but implementation dependent size as with int. + var pi float32 = 22. / 7 - // Conversion syntax with a short declaration. - n := byte('\n') // byte is an alias for uint8. + // Conversion syntax with a short declaration. + n := byte('\n') // byte is an alias for uint8. - // Arrays have size fixed at compile time. - var a4 [4]int // An array of 4 ints, initialized to all 0. - a3 := [...]int{3, 1, 5} // An array of 3 ints, initialized as shown. + // Arrays have size fixed at compile time. + var a4 [4]int // An array of 4 ints, initialized to all 0. + a3 := [...]int{3, 1, 5} // An array of 3 ints, initialized as shown. - // Slices have dynamic size. Arrays and slices each have advantages - // but use cases for slices are much more common. - s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here. - s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0. - var d2 [][]float64 // Declaration only, nothing allocated here. - bs := []byte("a slice") // Type conversion syntax. + // Slices have dynamic size. Arrays and slices each have advantages + // but use cases for slices are much more common. + s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here. + s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0. + var d2 [][]float64 // Declaration only, nothing allocated here. + bs := []byte("a slice") // Type conversion syntax. - p, q := learnMemory() // Declares p, q to be type pointer to int. - fmt.Println(*p, *q) // * follows a pointer. This prints two ints. + p, q := learnMemory() // Declares p, q to be type pointer to int. + fmt.Println(*p, *q) // * follows a pointer. This prints two ints. - // Maps are a dynamically growable associative array type, like the - // hash or dictionary types of some other languages. - m := map[string]int{"three": 3, "four": 4} - m["one"] = 1 + // Maps are a dynamically growable associative array type, like the + // hash or dictionary types of some other languages. + m := map[string]int{"three": 3, "four": 4} + m["one"] = 1 - // Unused variables are an error in Go. - // The underbar lets you "use" a variable but discard its value. - _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs - // Output of course counts as using a variable. - fmt.Println(s, c, a4, s3, d2, m) + // Unused variables are an error in Go. + // The underbar lets you "use" a variable but discard its value. + _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs + // Output of course counts as using a variable. + fmt.Println(s, c, a4, s3, d2, m) - learnFlowControl() // Back in the flow. + learnFlowControl() // Back in the flow. } // It is possible, unlike in many other languages for functions in go @@ -122,250 +124,249 @@ can include line breaks.` // Same string type. // allows us to easily return from multiple points in a function as well as to // only use the return keyword, without anything further. func learnNamedReturns(x, y int) (z int) { - z = x * y - return // z is implicit here, because we named it earlier. + z = x * y + return // z is implicit here, because we named it earlier. } // Go is fully garbage collected. It has pointers but no pointer arithmetic. // You can make a mistake with a nil pointer, but not by incrementing a pointer. func learnMemory() (p, q *int) { - // Named return values p and q have type pointer to int. - p = new(int) // Built-in function new allocates memory. - // The allocated int is initialized to 0, p is no longer nil. - s := make([]int, 20) // Allocate 20 ints as a single block of memory. - s[3] = 7 // Assign one of them. - r := -2 // Declare another local variable. - return &s[3], &r // & takes the address of an object. + // Named return values p and q have type pointer to int. + p = new(int) // Built-in function new allocates memory. + // The allocated int is initialized to 0, p is no longer nil. + s := make([]int, 20) // Allocate 20 ints as a single block of memory. + s[3] = 7 // Assign one of them. + r := -2 // Declare another local variable. + return &s[3], &r // & takes the address of an object. } func expensiveComputation() float64 { - return m.Exp(10) + return m.Exp(10) } func learnFlowControl() { - // If statements require brace brackets, and do not require parens. - if true { - fmt.Println("told ya") - } - // Formatting is standardized by the command line command "go fmt." - if false { - // Pout. - } else { - // Gloat. - } - // Use switch in preference to chained if statements. - x := 42.0 - switch x { - case 0: - case 1: - case 42: - // Cases don't "fall through". - case 43: - // Unreached. - } - // Like if, for doesn't use parens either. - // Variables declared in for and if are local to their scope. - for x := 0; x < 3; x++ { // ++ is a statement. - fmt.Println("iteration", x) - } - // x == 42 here. - - // For is the only loop statement in Go, but it has alternate forms. - for { // Infinite loop. - break // Just kidding. - continue // Unreached. - } - // As with for, := in an if statement means to declare and assign y first, - // then test y > x. - if y := expensiveComputation(); y > x { - x = y - } - // Function literals are closures. - xBig := func() bool { - return x > 10000 // References x declared above switch statement. - } - fmt.Println("xBig:", xBig()) // true (we last assigned e^10 to x). - x = 1.3e3 // This makes x == 1300 - fmt.Println("xBig:", xBig()) // false now. - - // What's more is function literals may be defined and called inline, - // acting as an argument to function, as long as: - // a) function literal is called immediately (), - // b) result type matches expected type of argument. - fmt.Println("Add + double two numbers: ", - func(a, b int) int { - return (a + b) * 2 - }(10, 2)) // Called with args 10 and 2 - // => Add + double two numbers: 24 - - // When you need it, you'll love it. - goto love + // If statements require brace brackets, and do not require parens. + if true { + fmt.Println("told ya") + } + // Formatting is standardized by the command line command "go fmt." + if false { + // Pout. + } else { + // Gloat. + } + // Use switch in preference to chained if statements. + x := 42.0 + switch x { + case 0: + case 1: + case 42: + // Cases don't "fall through". + case 43: + // Unreached. + } + // Like if, for doesn't use parens either. + // Variables declared in for and if are local to their scope. + for x := 0; x < 3; x++ { // ++ is a statement. + fmt.Println("iteration", x) + } + // x == 42 here. + + // For is the only loop statement in Go, but it has alternate forms. + for { // Infinite loop. + break // Just kidding. + continue // Unreached. + } + // As with for, := in an if statement means to declare and assign + // y first, then test y > x. + if y := expensiveComputation(); y > x { + x = y + } + // Function literals are closures. + xBig := func() bool { + return x > 10000 // References x declared above switch statement. + } + fmt.Println("xBig:", xBig()) // true (we last assigned e^10 to x). + x = 1.3e3 // This makes x == 1300 + fmt.Println("xBig:", xBig()) // false now. + + // What's more is function literals may be defined and called inline, + // acting as an argument to function, as long as: + // a) function literal is called immediately (), + // b) result type matches expected type of argument. + fmt.Println("Add + double two numbers: ", + func(a, b int) int { + return (a + b) * 2 + }(10, 2)) // Called with args 10 and 2 + // => Add + double two numbers: 24 + + // When you need it, you'll love it. + goto love love: - learnFunctionFactory() // func returning func is fun(3)(3) - learnDefer() // A quick detour to an important keyword. - learnInterfaces() // Good stuff coming up! + learnFunctionFactory() // func returning func is fun(3)(3) + learnDefer() // A quick detour to an important keyword. + learnInterfaces() // Good stuff coming up! } func learnFunctionFactory() { - // Next two are equivalent, with second being more practical - fmt.Println(sentenceFactory("summer")("A beautiful", "day!")) + // Next two are equivalent, with second being more practical + fmt.Println(sentenceFactory("summer")("A beautiful", "day!")) - d := sentenceFactory("summer") - fmt.Println(d("A beautiful", "day!")) - fmt.Println(d("A lazy", "afternoon!")) + d := sentenceFactory("summer") + fmt.Println(d("A beautiful", "day!")) + fmt.Println(d("A lazy", "afternoon!")) } // Decorators are common in other languages. Same can be done in Go // with function literals that accept arguments. func sentenceFactory(mystring string) func(before, after string) string { - return func(before, after string) string { - return fmt.Sprintf("%s %s %s", before, mystring, after) // new string - } + return func(before, after string) string { + return fmt.Sprintf("%s %s %s", before, mystring, after) // new string + } } func learnDefer() (ok bool) { - // Deferred statements are executed just before the function returns. - defer fmt.Println("deferred statements execute in reverse (LIFO) order.") - defer fmt.Println("\nThis line is being printed first because") - // Defer is commonly used to close a file, so the function closing the file - // stays close to the function opening the file - return true + // Deferred statements are executed just before the function returns. + defer fmt.Println("deferred statements execute in reverse (LIFO) order.") + defer fmt.Println("\nThis line is being printed first because") + // Defer is commonly used to close a file, so the function closing the + // file stays close to the function opening the file. + return true } // Define Stringer as an interface type with one method, String. type Stringer interface { - String() string + String() string } // Define pair as a struct with two fields, ints named x and y. type pair struct { - x, y int + x, y int } // Define a method on type pair. Pair now implements Stringer. func (p pair) String() string { // p is called the "receiver" - // Sprintf is another public function in package fmt. - // Dot syntax references fields of p. - return fmt.Sprintf("(%d, %d)", p.x, p.y) + // Sprintf is another public function in package fmt. + // Dot syntax references fields of p. + return fmt.Sprintf("(%d, %d)", p.x, p.y) } func learnInterfaces() { - // Brace syntax is a "struct literal." It evaluates to an initialized - // struct. The := syntax declares and initializes p to this struct. - p := pair{3, 4} - fmt.Println(p.String()) // Call String method of p, of type pair. - var i Stringer // Declare i of interface type Stringer. - i = p // Valid because pair implements Stringer - // Call String method of i, of type Stringer. Output same as above. - fmt.Println(i.String()) - - // Functions in the fmt package call the String method to ask an object - // for a printable representation of itself. - fmt.Println(p) // Output same as above. Println calls String method. - fmt.Println(i) // Output same as above. - - learnVariadicParams("great", "learning", "here!") + // Brace syntax is a "struct literal." It evaluates to an initialized + // struct. The := syntax declares and initializes p to this struct. + p := pair{3, 4} + fmt.Println(p.String()) // Call String method of p, of type pair. + var i Stringer // Declare i of interface type Stringer. + i = p // Valid because pair implements Stringer + // Call String method of i, of type Stringer. Output same as above. + fmt.Println(i.String()) + + // Functions in the fmt package call the String method to ask an object + // for a printable representation of itself. + fmt.Println(p) // Output same as above. Println calls String method. + fmt.Println(i) // Output same as above. + + learnVariadicParams("great", "learning", "here!") } // Functions can have variadic parameters. func learnVariadicParams(myStrings ...interface{}) { - // Iterate each value of the variadic. - // The underbar here is ignoring the index argument of the array. - for _, param := range myStrings { - fmt.Println("param:", param) - } + // Iterate each value of the variadic. + // The underbar here is ignoring the index argument of the array. + for _, param := range myStrings { + fmt.Println("param:", param) + } - // Pass variadic value as a variadic parameter. - fmt.Println("params:", fmt.Sprintln(myStrings...)) + // Pass variadic value as a variadic parameter. + fmt.Println("params:", fmt.Sprintln(myStrings...)) - learnErrorHandling() + learnErrorHandling() } func learnErrorHandling() { - // ", ok" idiom used to tell if something worked or not. - m := map[int]string{3: "three", 4: "four"} - if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map. - fmt.Println("no one there") - } else { - fmt.Print(x) // x would be the value, if it were in the map. - } - // An error value communicates not just "ok" but more about the problem. - if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value - // prints 'strconv.ParseInt: parsing "non-int": invalid syntax' - fmt.Println(err) - } - // We'll revisit interfaces a little later. Meanwhile, - learnConcurrency() + // ", ok" idiom used to tell if something worked or not. + m := map[int]string{3: "three", 4: "four"} + if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map. + fmt.Println("no one there") + } else { + fmt.Print(x) // x would be the value, if it were in the map. + } + // An error value communicates not just "ok" but more about the problem. + if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value + // prints 'strconv.ParseInt: parsing "non-int": invalid syntax' + fmt.Println(err) + } + // We'll revisit interfaces a little later. Meanwhile, + learnConcurrency() } // c is a channel, a concurrency-safe communication object. func inc(i int, c chan int) { - c <- i + 1 // <- is the "send" operator when a channel appears on the left. + c <- i + 1 // <- is the "send" operator when a channel appears on the left. } // We'll use inc to increment some numbers concurrently. func learnConcurrency() { - // Same make function used earlier to make a slice. Make allocates and - // initializes slices, maps, and channels. - c := make(chan int) - // Start three concurrent goroutines. Numbers will be incremented - // concurrently, perhaps in parallel if the machine is capable and - // properly configured. All three send to the same channel. - go inc(0, c) // go is a statement that starts a new goroutine. - go inc(10, c) - go inc(-805, c) - // Read three results from the channel and print them out. - // There is no telling in what order the results will arrive! - fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator. - - cs := make(chan string) // Another channel, this one handles strings. - ccs := make(chan chan string) // A channel of string channels. - go func() { c <- 84 }() // Start a new goroutine just to send a value. - go func() { cs <- "wordy" }() // Again, for cs this time. - // Select has syntax like a switch statement but each case involves - // a channel operation. It selects a case at random out of the cases - // that are ready to communicate. - select { - case i := <-c: // The value received can be assigned to a variable, - fmt.Printf("it's a %T", i) - case <-cs: // or the value received can be discarded. - fmt.Println("it's a string") - case <-ccs: // Empty channel, not ready for communication. - fmt.Println("didn't happen.") - } - // At this point a value was taken from either c or cs. One of the two - // goroutines started above has completed, the other will remain blocked. - - learnWebProgramming() // Go does it. You want to do it too. + // Same make function used earlier to make a slice. Make allocates and + // initializes slices, maps, and channels. + c := make(chan int) + // Start three concurrent goroutines. Numbers will be incremented + // concurrently, perhaps in parallel if the machine is capable and + // properly configured. All three send to the same channel. + go inc(0, c) // go is a statement that starts a new goroutine. + go inc(10, c) + go inc(-805, c) + // Read three results from the channel and print them out. + // There is no telling in what order the results will arrive! + fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator. + + cs := make(chan string) // Another channel, this one handles strings. + ccs := make(chan chan string) // A channel of string channels. + go func() { c <- 84 }() // Start a new goroutine just to send a value. + go func() { cs <- "wordy" }() // Again, for cs this time. + // Select has syntax like a switch statement but each case involves + // a channel operation. It selects a case at random out of the cases + // that are ready to communicate. + select { + case i := <-c: // The value received can be assigned to a variable, + fmt.Printf("it's a %T", i) + case <-cs: // or the value received can be discarded. + fmt.Println("it's a string") + case <-ccs: // Empty channel, not ready for communication. + fmt.Println("didn't happen.") + } + // At this point a value was taken from either c or cs. One of the two + // goroutines started above has completed, the other will remain blocked. + + learnWebProgramming() // Go does it. You want to do it too. } // A single function from package http starts a web server. func learnWebProgramming() { - // First parameter of ListenAndServe is TCP address to listen to. - // Second parameter is an interface, specifically http.Handler. - go func() { - err := http.ListenAndServe(":8080", pair{}) - fmt.Println(err) // don't ignore errors - }() + // First parameter of ListenAndServe is TCP address to listen to. + // Second parameter is an interface, specifically http.Handler. + go func() { + err := http.ListenAndServe(":8080", pair{}) + fmt.Println(err) // don't ignore errors + }() - requestServer(); + requestServer() } - // Make pair an http.Handler by implementing its only method, ServeHTTP. func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Serve data with a method of http.ResponseWriter. - w.Write([]byte("You learned Go in Y minutes!")) + // Serve data with a method of http.ResponseWriter. + w.Write([]byte("You learned Go in Y minutes!")) } func requestServer() { - resp, err := http.Get("http://localhost:8080") - fmt.Println(err) - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - fmt.Printf("\nWebserver said: `%s`", string(body)) + resp, err := http.Get("http://localhost:8080") + fmt.Println(err) + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + fmt.Printf("\nWebserver said: `%s`", string(body)) } ``` -- cgit v1.2.3 From cfa26f23fd4f65896f01df2997f64c5ca184f484 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Bohin Date: Mon, 4 Aug 2014 22:23:24 +0200 Subject: [go/en] add an example for range - fixes #351 --- go.html.markdown | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index a1be08af..77961524 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -177,6 +177,14 @@ func learnFlowControl() { break // Just kidding. continue // Unreached. } + + // you can use range to iterate over an array, a slice, a string, a map, or a channel. + // range returns one (channel) or two values (array, slice, string and map) + for key, value := range map[string]int{"one": 1, "two": 2, "three": 3} { + // for each pair in the map, print key and value + fmt.Printf("key=%s, value=%d\n", key, value) + } + // As with for, := in an if statement means to declare and assign // y first, then test y > x. if y := expensiveComputation(); y > x { -- cgit v1.2.3 From 0078b03707eeccf50e5bb1d7230e88b4ce3d36be Mon Sep 17 00:00:00 2001 From: Jean-Christophe Bohin Date: Mon, 4 Aug 2014 22:38:53 +0200 Subject: Array initialization disambiguation - fixes #257 simply added proposed comment, which seems fine --- go.html.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index a1be08af..6c4d88bd 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -92,7 +92,8 @@ can include line breaks.` // Same string type. // Arrays have size fixed at compile time. var a4 [4]int // An array of 4 ints, initialized to all 0. - a3 := [...]int{3, 1, 5} // An array of 3 ints, initialized as shown. + a3 := [...]int{3, 1, 5} // An array initialzed with a fixed size of three + //elements, with values 3,1, and 5 // Slices have dynamic size. Arrays and slices each have advantages // but use cases for slices are much more common. -- cgit v1.2.3 From 2ffd79293239dd5c0a85a18500e83f362991e062 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Bohin Date: Tue, 5 Aug 2014 09:03:21 +0200 Subject: Adding Go playground link with code - fixes #318 Just removed networking code, since Go playground's sandbox prevent it to work. --- go.html.markdown | 2 ++ 1 file changed, 2 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index a1be08af..88c98c21 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -378,6 +378,8 @@ There you can follow the tutorial, play interactively, and read lots. The language definition itself is highly recommended. It's easy to read and amazingly short (as language definitions go these days.) +You can play around with the code on [Go playground](https://play.golang.org/p/tnWMjr16Mm). Try to change it and run it from your browser! + On the reading list for students of Go is the [source code to the standard library](http://golang.org/src/pkg/). Comprehensively documented, it demonstrates the best of readable and understandable Go, Go style, and Go -- cgit v1.2.3 From a4b4a7927f958370ff706919fefa653d98a1f1ce Mon Sep 17 00:00:00 2001 From: Jean-Christophe Bohin Date: Thu, 7 Aug 2014 22:31:20 +0200 Subject: Adding a direct link to play.golang.org --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 88c98c21..088d4fe6 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -378,7 +378,7 @@ There you can follow the tutorial, play interactively, and read lots. The language definition itself is highly recommended. It's easy to read and amazingly short (as language definitions go these days.) -You can play around with the code on [Go playground](https://play.golang.org/p/tnWMjr16Mm). Try to change it and run it from your browser! +You can play around with the code on [Go playground](https://play.golang.org/p/tnWMjr16Mm). Try to change it and run it from your browser! Note that you can use [https://play.golang.org](https://play.golang.org) as a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) to test things and code in your browser, without even installing Go. On the reading list for students of Go is the [source code to the standard library](http://golang.org/src/pkg/). Comprehensively documented, it -- cgit v1.2.3 From c0d49cdb88a41ecea12cc98ca8ee04956b9c0d7b Mon Sep 17 00:00:00 2001 From: Jean-Christophe Bohin Date: Thu, 7 Aug 2014 22:37:52 +0200 Subject: Fixing missing space and dot. --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 6c4d88bd..5247ecf8 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -93,7 +93,7 @@ can include line breaks.` // Same string type. // Arrays have size fixed at compile time. var a4 [4]int // An array of 4 ints, initialized to all 0. a3 := [...]int{3, 1, 5} // An array initialzed with a fixed size of three - //elements, with values 3,1, and 5 + // elements, with values 3, 1, and 5. // Slices have dynamic size. Arrays and slices each have advantages // but use cases for slices are much more common. -- cgit v1.2.3 From 26166afc65772f31b4f189124019d9df85bbbadf Mon Sep 17 00:00:00 2001 From: Jean-Christophe Bohin Date: Thu, 7 Aug 2014 22:43:59 +0200 Subject: Fixed style Didn't uppercased 'range' in the beginning of the sentence since it's a language keyword. --- go.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 77961524..02ea280d 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -178,8 +178,8 @@ func learnFlowControl() { continue // Unreached. } - // you can use range to iterate over an array, a slice, a string, a map, or a channel. - // range returns one (channel) or two values (array, slice, string and map) + // You can use range to iterate over an array, a slice, a string, a map, or a channel. + // range returns one (channel) or two values (array, slice, string and map). for key, value := range map[string]int{"one": 1, "two": 2, "three": 3} { // for each pair in the map, print key and value fmt.Printf("key=%s, value=%d\n", key, value) -- cgit v1.2.3 From d7ead48d1fa7c6ffb32aeeb6f289bf859a6bbef8 Mon Sep 17 00:00:00 2001 From: James Baxter Date: Tue, 19 Aug 2014 12:06:02 +0100 Subject: Corrected the statement that rune is an alias for uint32 to say int32 --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 656b1051..f7bd8ee3 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -78,7 +78,7 @@ func learnTypes() { can include line breaks.` // Same string type. // Non-ASCII literal. Go source is UTF-8. - g := 'Σ' // rune type, an alias for uint32, holds a unicode code point. + g := 'Σ' // rune type, an alias for int32, holds a unicode code point. f := 3.14195 // float64, an IEEE-754 64-bit floating point number. c := 3 + 4i // complex128, represented internally with two float64's. -- cgit v1.2.3 From a7a8c85257ee48b92913018a3c221a9703c6d59b Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Sun, 10 Aug 2014 20:02:31 -0700 Subject: In golang slices are dynamic, so a mention of append() for slice updates seems to be appropriate. --- go.html.markdown | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index f7bd8ee3..390e36dc 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -101,6 +101,20 @@ can include line breaks.` // Same string type. var d2 [][]float64 // Declaration only, nothing allocated here. bs := []byte("a slice") // Type conversion syntax. + // Because they are dynamic, slices can be appended to on-demand. + // To append elements to a slice, built-in append() function is used. + // First argument is a slice to which we are appending. Commonly, + // the array variable is updated in place, as in example below. + s := []int{1, 2, 3} // Result is a slice of length 3. + s = append(s, 4, 5, 6) // Added 3 elements. Slice now has length of 6. + fmt.Println(s) // Updated slice is now [1 2 3 4 5 6] + // To append another slice, instead of list of atomic elements we can + // pass a reference to a slice or a slice literal like this, with a + // trailing elipsis, meaning take an array and unpack its elements, + // appending them to the slice. + s = append(s, []int{7, 8, 9}...) // Second argument is an array literal. + fmt.Println(s) // Updated slice is now [1 2 3 4 5 6 7 8 9] + p, q := learnMemory() // Declares p, q to be type pointer to int. fmt.Println(*p, *q) // * follows a pointer. This prints two ints. -- cgit v1.2.3 From 7000db24e040d712f963efa4dda70a9b3b99e3f8 Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Sun, 10 Aug 2014 20:04:49 -0700 Subject: Fixed indentation error created in previous commit. --- go.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 390e36dc..ddedd25e 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -107,13 +107,13 @@ can include line breaks.` // Same string type. // the array variable is updated in place, as in example below. s := []int{1, 2, 3} // Result is a slice of length 3. s = append(s, 4, 5, 6) // Added 3 elements. Slice now has length of 6. - fmt.Println(s) // Updated slice is now [1 2 3 4 5 6] - // To append another slice, instead of list of atomic elements we can + fmt.Println(s) // Updated slice is now [1 2 3 4 5 6] + // To append another slice, instead of list of atomic elements we can // pass a reference to a slice or a slice literal like this, with a // trailing elipsis, meaning take an array and unpack its elements, // appending them to the slice. s = append(s, []int{7, 8, 9}...) // Second argument is an array literal. - fmt.Println(s) // Updated slice is now [1 2 3 4 5 6 7 8 9] + fmt.Println(s) // Updated slice is now [1 2 3 4 5 6 7 8 9] p, q := learnMemory() // Declares p, q to be type pointer to int. fmt.Println(*p, *q) // * follows a pointer. This prints two ints. -- cgit v1.2.3 From 161e19baa96e3c9dbc5e8682cf3ef08bc6723a2e Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Tue, 19 Aug 2014 20:43:18 -0700 Subject: Minor language change fixing mixed use of array and slice, where only slice is correct. --- go.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index ddedd25e..c85209e0 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -110,9 +110,9 @@ can include line breaks.` // Same string type. fmt.Println(s) // Updated slice is now [1 2 3 4 5 6] // To append another slice, instead of list of atomic elements we can // pass a reference to a slice or a slice literal like this, with a - // trailing elipsis, meaning take an array and unpack its elements, - // appending them to the slice. - s = append(s, []int{7, 8, 9}...) // Second argument is an array literal. + // trailing elipsis, meaning take a slice and unpack its elements, + // appending them to slice s. + s = append(s, []int{7, 8, 9}...) // Second argument is a slice literal. fmt.Println(s) // Updated slice is now [1 2 3 4 5 6 7 8 9] p, q := learnMemory() // Declares p, q to be type pointer to int. -- cgit v1.2.3 From 0846eaa0e71cdcd651edf1c58b459520be844567 Mon Sep 17 00:00:00 2001 From: Nami-Doc Date: Fri, 5 Sep 2014 15:05:13 +0200 Subject: EDOUBLEDSPACE My *fake* ocd kicked in --- go.html.markdown | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index c85209e0..bedc3042 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -12,7 +12,7 @@ contributors: - ["Alexej Friesen", "https://github.com/heyalexej"] --- -Go was created out of the need to get work done. It's not the latest trend +Go was created out of the need to get work done. It's not the latest trend in computer science, but it is the newest fastest way to solve real-world problems. @@ -26,7 +26,7 @@ Go comes with a great standard library and an enthusiastic community. ```go // Single line comment /* Multi- - line comment */ + line comment */ // A package clause starts every source file. // Main is a special name declaring an executable rather than a library. @@ -41,8 +41,8 @@ import ( "strconv" // String conversions. ) -// A function definition. Main is special. It is the entry point for the -// executable program. Love it or hate it, Go uses brace brackets. +// A function definition. Main is special. It is the entry point for the +// executable program. Love it or hate it, Go uses brace brackets. func main() { // Println outputs a line to stdout. // Qualify it with the package name, fmt. @@ -77,7 +77,7 @@ func learnTypes() { s2 := `A "raw" string literal can include line breaks.` // Same string type. - // Non-ASCII literal. Go source is UTF-8. + // Non-ASCII literal. Go source is UTF-8. g := 'Σ' // rune type, an alias for int32, holds a unicode code point. f := 3.14195 // float64, an IEEE-754 64-bit floating point number. @@ -94,9 +94,9 @@ can include line breaks.` // Same string type. var a4 [4]int // An array of 4 ints, initialized to all 0. a3 := [...]int{3, 1, 5} // An array of 3 ints, initialized as shown. - // Slices have dynamic size. Arrays and slices each have advantages + // Slices have dynamic size. Arrays and slices each have advantages // but use cases for slices are much more common. - s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here. + s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here. s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0. var d2 [][]float64 // Declaration only, nothing allocated here. bs := []byte("a slice") // Type conversion syntax. @@ -116,7 +116,7 @@ can include line breaks.` // Same string type. fmt.Println(s) // Updated slice is now [1 2 3 4 5 6 7 8 9] p, q := learnMemory() // Declares p, q to be type pointer to int. - fmt.Println(*p, *q) // * follows a pointer. This prints two ints. + fmt.Println(*p, *q) // * follows a pointer. This prints two ints. // Maps are a dynamically growable associative array type, like the // hash or dictionary types of some other languages. @@ -142,7 +142,7 @@ func learnNamedReturns(x, y int) (z int) { return // z is implicit here, because we named it earlier. } -// Go is fully garbage collected. It has pointers but no pointer arithmetic. +// Go is fully garbage collected. It has pointers but no pointer arithmetic. // You can make a mistake with a nil pointer, but not by incrementing a pointer. func learnMemory() (p, q *int) { // Named return values p and q have type pointer to int. @@ -220,7 +220,7 @@ func learnFlowControl() { func(a, b int) int { return (a + b) * 2 }(10, 2)) // Called with args 10 and 2 - // => Add + double two numbers: 24 + // => Add + double two numbers: 24 // When you need it, you'll love it. goto love @@ -267,7 +267,7 @@ type pair struct { x, y int } -// Define a method on type pair. Pair now implements Stringer. +// Define a method on type pair. Pair now implements Stringer. func (p pair) String() string { // p is called the "receiver" // Sprintf is another public function in package fmt. // Dot syntax references fields of p. @@ -275,13 +275,13 @@ func (p pair) String() string { // p is called the "receiver" } func learnInterfaces() { - // Brace syntax is a "struct literal." It evaluates to an initialized - // struct. The := syntax declares and initializes p to this struct. + // Brace syntax is a "struct literal". It evaluates to an initialized + // struct. The := syntax declares and initializes p to this struct. p := pair{3, 4} fmt.Println(p.String()) // Call String method of p, of type pair. var i Stringer // Declare i of interface type Stringer. i = p // Valid because pair implements Stringer - // Call String method of i, of type Stringer. Output same as above. + // Call String method of i, of type Stringer. Output same as above. fmt.Println(i.String()) // Functions in the fmt package call the String method to ask an object @@ -319,7 +319,7 @@ func learnErrorHandling() { // prints 'strconv.ParseInt: parsing "non-int": invalid syntax' fmt.Println(err) } - // We'll revisit interfaces a little later. Meanwhile, + // We'll revisit interfaces a little later. Meanwhile, learnConcurrency() } @@ -330,12 +330,12 @@ func inc(i int, c chan int) { // We'll use inc to increment some numbers concurrently. func learnConcurrency() { - // Same make function used earlier to make a slice. Make allocates and + // Same make function used earlier to make a slice. Make allocates and // initializes slices, maps, and channels. c := make(chan int) - // Start three concurrent goroutines. Numbers will be incremented + // Start three concurrent goroutines. Numbers will be incremented // concurrently, perhaps in parallel if the machine is capable and - // properly configured. All three send to the same channel. + // properly configured. All three send to the same channel. go inc(0, c) // go is a statement that starts a new goroutine. go inc(10, c) go inc(-805, c) @@ -348,7 +348,7 @@ func learnConcurrency() { go func() { c <- 84 }() // Start a new goroutine just to send a value. go func() { cs <- "wordy" }() // Again, for cs this time. // Select has syntax like a switch statement but each case involves - // a channel operation. It selects a case at random out of the cases + // a channel operation. It selects a case at random out of the cases // that are ready to communicate. select { case i := <-c: // The value received can be assigned to a variable, @@ -358,7 +358,7 @@ func learnConcurrency() { case <-ccs: // Empty channel, not ready for communication. fmt.Println("didn't happen.") } - // At this point a value was taken from either c or cs. One of the two + // At this point a value was taken from either c or cs. One of the two // goroutines started above has completed, the other will remain blocked. learnWebProgramming() // Go does it. You want to do it too. @@ -397,15 +397,15 @@ func requestServer() { The root of all things Go is the [official Go web site](http://golang.org/). There you can follow the tutorial, play interactively, and read lots. -The language definition itself is highly recommended. It's easy to read +The language definition itself is highly recommended. It's easy to read and amazingly short (as language definitions go these days.) You can play around with the code on [Go playground](https://play.golang.org/p/tnWMjr16Mm). Try to change it and run it from your browser! Note that you can use [https://play.golang.org](https://play.golang.org) as a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) to test things and code in your browser, without even installing Go. On the reading list for students of Go is the [source code to the standard -library](http://golang.org/src/pkg/). Comprehensively documented, it +library](http://golang.org/src/pkg/). Comprehensively documented, it demonstrates the best of readable and understandable Go, Go style, and Go -idioms. Or you can click on a function name in [the +idioms. Or you can click on a function name in [the documentation](http://golang.org/pkg/) and the source code comes up! Another great resource to learn Go is [Go by example](https://gobyexample.com/). -- cgit v1.2.3 From 291f6f6b22acf7962a180e6e12234aebcb20c5bd Mon Sep 17 00:00:00 2001 From: Levi Bostian Date: Fri, 5 Sep 2014 21:02:38 -0500 Subject: Fix "initialized" typo. --- go.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 758c9ff4..b4c6afff 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -92,7 +92,7 @@ can include line breaks.` // Same string type. // Arrays have size fixed at compile time. var a4 [4]int // An array of 4 ints, initialized to all 0. - a3 := [...]int{3, 1, 5} // An array initialzed with a fixed size of three + a3 := [...]int{3, 1, 5} // An array initialized with a fixed size of three // elements, with values 3, 1, and 5. // Slices have dynamic size. Arrays and slices each have advantages -- cgit v1.2.3 From 5e5a7a19feb42afad6b678cc970db2ea248fcc9b Mon Sep 17 00:00:00 2001 From: kb Date: Mon, 22 Sep 2014 12:11:49 +0000 Subject: [go] Fix no new variables on left side of := Cannot short declaration twice without at least one new var. Also changing type from string to slice. $ go run learnxiny.go # command-line-arguments ./learnxiny.go:83: no new variables on left side of := ./learnxiny.go:83: cannot use []int literal (type []int) as type string in assignment ./learnxiny.go:84: first argument to append must be slice; have string ./learnxiny.go:90: first argument to append must be slice; have string --- go.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index b4c6afff..17f10bd9 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -72,7 +72,7 @@ func learnMultiple(x, y int) (sum, prod int) { // Some built-in types and literals. func learnTypes() { // Short declaration usually gives you what you want. - s := "Learn Go!" // string type. + str := "Learn Go!" // string type. s2 := `A "raw" string literal can include line breaks.` // Same string type. @@ -126,7 +126,7 @@ can include line breaks.` // Same string type. // Unused variables are an error in Go. // The underbar lets you "use" a variable but discard its value. - _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs + _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs // Output of course counts as using a variable. fmt.Println(s, c, a4, s3, d2, m) -- cgit v1.2.3 From f63032d2f216d62d149a8dc2f1df919999c41938 Mon Sep 17 00:00:00 2001 From: Kev Choi Date: Mon, 20 Apr 2015 23:26:38 -0700 Subject: Add default case to switch statement in Go --- go.html.markdown | 2 ++ 1 file changed, 2 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 17f10bd9..9b9758b4 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -179,6 +179,8 @@ func learnFlowControl() { // Cases don't "fall through". case 43: // Unreached. + default: + // Default case is optional. } // Like if, for doesn't use parens either. // Variables declared in for and if are local to their scope. -- cgit v1.2.3 From 3bf74b3ddae006353069218563cbcd370c88aaaa Mon Sep 17 00:00:00 2001 From: Samuel Marks Date: Wed, 22 Apr 2015 23:54:16 +1000 Subject: Fixed grammar, added explanation of function signature and arguments --- go.html.markdown | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 9b9758b4..9fce7a9b 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -64,7 +64,11 @@ func beyondHello() { learnTypes() // < y minutes, learn more! } -// Functions can have parameters and (multiple!) return values. +/* <- multiline comment +Functions can have parameters and (multiple!) return values. +Here `x`, `y` are the arguments and `sum`, `prod` is the signature (what's returned). +Note that `x` and `sum` receive the type `int`. +*/ func learnMultiple(x, y int) (sum, prod int) { return x + y, x * y // Return two values. } @@ -83,7 +87,7 @@ can include line breaks.` // Same string type. f := 3.14195 // float64, an IEEE-754 64-bit floating point number. c := 3 + 4i // complex128, represented internally with two float64's. - // Var syntax with an initializers. + // var syntax with initializers. var u uint = 7 // Unsigned, but implementation dependent size as with int. var pi float32 = 22. / 7 -- cgit v1.2.3 From 1faab2901edb8c2e1eda708af8b37f3ec62dfd78 Mon Sep 17 00:00:00 2001 From: Samuel Marks Date: Thu, 23 Apr 2015 00:02:33 +1000 Subject: Fallthrough --- go.html.markdown | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'go.html.markdown') diff --git a/go.html.markdown b/go.html.markdown index 9fce7a9b..34b855e3 100644 --- a/go.html.markdown +++ b/go.html.markdown @@ -181,6 +181,10 @@ func learnFlowControl() { case 1: case 42: // Cases don't "fall through". + /* + There is a `fallthrough` keyword however, see: + https://github.com/golang/go/wiki/Switch#fall-through + */ case 43: // Unreached. default: -- cgit v1.2.3