go by example part 2
This commit is contained in:
parent
afe165089d
commit
c1b7c64da2
38
5-go-by-example/11-range.go
Normal file
38
5-go-by-example/11-range.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// range iterates over elements in a variety of data structures
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// use range to sum the numbers in a slice
|
||||||
|
nums := []int{2, 3, 4}
|
||||||
|
sum := 0
|
||||||
|
for _, num := range nums {
|
||||||
|
sum += num
|
||||||
|
}
|
||||||
|
fmt.Println("sum:", sum)
|
||||||
|
|
||||||
|
// range on arrays and slices provides both the index and value for each entry
|
||||||
|
for i, num := range nums {
|
||||||
|
if num == 3 {
|
||||||
|
fmt.Println("index:", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// range on map iterates over key/value pairs
|
||||||
|
kvs := map[string]string{"a": "apple", "b": "banana"}
|
||||||
|
for k, v := range kvs {
|
||||||
|
fmt.Printf("%s -> %s\n", k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// range iterate over keys of a map
|
||||||
|
for k := range kvs {
|
||||||
|
fmt.Println("key:", k)
|
||||||
|
}
|
||||||
|
|
||||||
|
// range on strings iterates over Unicode code points
|
||||||
|
for i, c := range "go" {
|
||||||
|
fmt.Println(i, c)
|
||||||
|
}
|
||||||
|
}
|
24
5-go-by-example/12-function.go
Normal file
24
5-go-by-example/12-function.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// function that takes two ints and returns their sum as an int
|
||||||
|
// Go requires explicit returns
|
||||||
|
func plus(a int, b int) int {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiple consecutive parameters of the same type,
|
||||||
|
// may omit the type name for the like-typed parameters up to the final parameter that declares the type
|
||||||
|
func plusPlus(a, b, c int) int {
|
||||||
|
return a + b + c
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Call a function
|
||||||
|
res := plus(1, 2)
|
||||||
|
fmt.Println("1+2 =", res)
|
||||||
|
|
||||||
|
res = plusPlus(1, 2, 3)
|
||||||
|
fmt.Println("1+2+3 =", res)
|
||||||
|
}
|
20
5-go-by-example/13-muliple-return-value.go
Normal file
20
5-go-by-example/13-muliple-return-value.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// (int, int) in this function signature shows that the function returns 2 ints
|
||||||
|
func vals() (int, int) {
|
||||||
|
return 3, 7
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// use the 2 different return values
|
||||||
|
a, b := vals()
|
||||||
|
fmt.Println(a)
|
||||||
|
fmt.Println(b)
|
||||||
|
|
||||||
|
// use the blank identifier _
|
||||||
|
_, c := vals()
|
||||||
|
fmt.Println(c)
|
||||||
|
}
|
26
5-go-by-example/14-variadic-function.go
Normal file
26
5-go-by-example/14-variadic-function.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Variadic functions can be called with any number of trailing arguments
|
||||||
|
|
||||||
|
// take an arbitrary number of ints as arguments
|
||||||
|
func sum(nums ...int) {
|
||||||
|
fmt.Print(nums, " ")
|
||||||
|
total := 0
|
||||||
|
for _, num := range nums {
|
||||||
|
total += num
|
||||||
|
}
|
||||||
|
fmt.Println(total)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Variadic functions can be called in the usual way
|
||||||
|
sum(1, 2)
|
||||||
|
sum(1, 2, 3)
|
||||||
|
|
||||||
|
// apply multiple args to a variadic function
|
||||||
|
nums := []int{1, 2, 3, 4}
|
||||||
|
sum(nums...)
|
||||||
|
}
|
29
5-go-by-example/15-closures.go
Normal file
29
5-go-by-example/15-closures.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Go supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.
|
||||||
|
|
||||||
|
// intSeq returns another function, which is defined anonymously in the body of intSeq
|
||||||
|
// the returned function closes over the variable i to form a closure
|
||||||
|
func intSeq() func() int {
|
||||||
|
i := 0
|
||||||
|
return func() int {
|
||||||
|
i++
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// call intSeq, assigning the result (a function) to nextInt
|
||||||
|
nextInt := intSeq()
|
||||||
|
|
||||||
|
// see the effect of the closure
|
||||||
|
fmt.Println(nextInt())
|
||||||
|
fmt.Println(nextInt())
|
||||||
|
fmt.Println(nextInt())
|
||||||
|
|
||||||
|
// confirm that the state is unique to that particular function
|
||||||
|
newInts := intSeq()
|
||||||
|
fmt.Println(newInts())
|
||||||
|
}
|
29
5-go-by-example/16-recursion.go
Normal file
29
5-go-by-example/16-recursion.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// fact function calls itself until it reaches the base case of fact(0)
|
||||||
|
func fact(n int) int {
|
||||||
|
if n == 0 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return n * fact(n-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(fact(7))
|
||||||
|
|
||||||
|
// Closures can also be recursive, but this requires the closure to be declared with a typed var explicitly before it’s defined
|
||||||
|
var fib func(n int) int
|
||||||
|
|
||||||
|
// Go knows which function to call with fib as it is defined previously in main
|
||||||
|
fib = func(n int) int {
|
||||||
|
if n < 2 {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
return fib(n-1) + fib(n-2)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(fib(7))
|
||||||
|
}
|
33
5-go-by-example/17-pointers.go
Normal file
33
5-go-by-example/17-pointers.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Go supports pointers, allowing you to pass references to values and records within your program
|
||||||
|
|
||||||
|
// zeroval has an int parameter, so arguments will be passed to it by value
|
||||||
|
// zeroval will get a copy of ival distinct from the one in the calling function
|
||||||
|
func zeroval(ival int) {
|
||||||
|
ival = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// zeroptr has an *int parameter, meaning that it takes an int pointer
|
||||||
|
// the *iptr code in the function body then dereferences the pointer from its memory address to the current value at that address
|
||||||
|
// assigning a value to a dereferenced pointer changes the value at the referenced address
|
||||||
|
func zeroptr(iptr *int) {
|
||||||
|
*iptr = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
i := 1
|
||||||
|
fmt.Println("initial:", i)
|
||||||
|
|
||||||
|
zeroval(i)
|
||||||
|
fmt.Println("zeroval:", i)
|
||||||
|
|
||||||
|
// &i syntax gives the memory address
|
||||||
|
zeroptr(&i)
|
||||||
|
fmt.Println("zeroptr:", i)
|
||||||
|
|
||||||
|
// Pointers can be printed
|
||||||
|
fmt.Println("pointer:", &i)
|
||||||
|
}
|
49
5-go-by-example/18-structs.go
Normal file
49
5-go-by-example/18-structs.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Go’s structs are typed collections of fields. They’re useful for grouping data together to form records.
|
||||||
|
|
||||||
|
// this person struct type has name and age fields
|
||||||
|
type person struct {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
}
|
||||||
|
|
||||||
|
// newPerson constructs a new person struct with the given name
|
||||||
|
// safely return a pointer to local variable as a local variable will survive the scope of the function
|
||||||
|
func newPerson(name string) *person {
|
||||||
|
p := person{name: name}
|
||||||
|
p.age = 42
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// create a new struct
|
||||||
|
fmt.Println(person{"Bob", 20})
|
||||||
|
|
||||||
|
// name the fields when initializing a struct
|
||||||
|
fmt.Println(person{name: "Alice", age: 30})
|
||||||
|
|
||||||
|
// omitted fields will be zero-valued
|
||||||
|
fmt.Println(person{name: "Fred"})
|
||||||
|
|
||||||
|
// & prefix yields a pointer to the struct
|
||||||
|
fmt.Println(&person{name: "Ann", age: 40})
|
||||||
|
|
||||||
|
// encapsulate new struct creation in constructor functions (ideomatic)
|
||||||
|
fmt.Println(newPerson("Jon"))
|
||||||
|
|
||||||
|
// access struct fields with a dot
|
||||||
|
s := person{name: "Sean", age: 50}
|
||||||
|
fmt.Println(s.name)
|
||||||
|
|
||||||
|
// use dots with struct pointers
|
||||||
|
// the pointers are automatically dereferenced
|
||||||
|
sp := &s
|
||||||
|
fmt.Println(sp.age)
|
||||||
|
|
||||||
|
// structs are mutable
|
||||||
|
sp.age = 51
|
||||||
|
fmt.Println(sp.age)
|
||||||
|
}
|
32
5-go-by-example/19-methods.go
Normal file
32
5-go-by-example/19-methods.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// methods defined on struct types
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type rect struct {
|
||||||
|
width, height int
|
||||||
|
}
|
||||||
|
|
||||||
|
// area method has a receiver type of *rect
|
||||||
|
func (r *rect) area() int {
|
||||||
|
return r.width * r.height
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods can be defined for either pointer or value receiver types
|
||||||
|
func (r rect) perim() int {
|
||||||
|
return 2*r.width + 2*r.height
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := rect{width: 10, height: 5}
|
||||||
|
|
||||||
|
// call 2 methods defined for the struct
|
||||||
|
fmt.Println("area: ", r.area())
|
||||||
|
fmt.Println("perim:", r.perim())
|
||||||
|
|
||||||
|
// Go automatically handles conversion between values and pointers for method calls
|
||||||
|
rp := &r
|
||||||
|
fmt.Println("area: ", rp.area())
|
||||||
|
fmt.Println("perim:", rp.perim())
|
||||||
|
}
|
55
5-go-by-example/20-interfaces.go
Normal file
55
5-go-by-example/20-interfaces.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Interfaces are named collections of method signatures
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
// basic interface for geometric shapes
|
||||||
|
type geometry interface {
|
||||||
|
area() float64
|
||||||
|
perim() float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// implement interface on rect and circle types
|
||||||
|
type rect struct {
|
||||||
|
width, height float64
|
||||||
|
}
|
||||||
|
type circle struct {
|
||||||
|
radius float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// implement geometry on rects
|
||||||
|
func (r rect) area() float64 {
|
||||||
|
return r.width * r.height
|
||||||
|
}
|
||||||
|
func (r rect) perim() float64 {
|
||||||
|
return 2*r.width + 2*r.height
|
||||||
|
}
|
||||||
|
|
||||||
|
// implementation for circles
|
||||||
|
func (c circle) area() float64 {
|
||||||
|
return math.Pi * c.radius * c.radius
|
||||||
|
}
|
||||||
|
func (c circle) perim() float64 {
|
||||||
|
return 2 * math.Pi * c.radius
|
||||||
|
}
|
||||||
|
|
||||||
|
// call methods that are in the named interface
|
||||||
|
func measure(g geometry) {
|
||||||
|
fmt.Println(g)
|
||||||
|
fmt.Println(g.area())
|
||||||
|
fmt.Println(g.perim())
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
r := rect{width: 3, height: 4}
|
||||||
|
c := circle{radius: 5}
|
||||||
|
|
||||||
|
// circle and rect struct types both implement the geometry interface
|
||||||
|
// use instances of these structs as arguments to measure
|
||||||
|
measure(r)
|
||||||
|
measure(c)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user