fix: coding style and file format for all example.

This commit is contained in:
Bo-Yi Wu
2017-02-11 12:34:46 +08:00
parent f215102638
commit 416e29d95a
206 changed files with 5531 additions and 5451 deletions

View File

@@ -1,43 +1,44 @@
package main package main
import ( import (
"fmt" "fmt"
) )
type Log struct { type Log struct {
msg string msg string
} }
type Customer struct { type Customer struct {
Name string Name string
log *Log log *Log
} }
func main() { func main() {
// c := new(Customer) // c := new(Customer)
// c.Name = "Barak Obama" // c.Name = "Barak Obama"
// c.log = new(Log) // c.log = new(Log)
// c.log.msg = "1 - Yes we can!" // c.log.msg = "1 - Yes we can!"
// shorter: // shorter:
c := &Customer{"Barak Obama", &Log{"1 - Yes we can!"}} c := &Customer{"Barak Obama", &Log{"1 - Yes we can!"}}
// fmt.Println(c) // &{Barak Obama 1 - Yes we can!} // fmt.Println(c) // &{Barak Obama 1 - Yes we can!}
c.Log().Add("2 - After me the world will be a better place!") c.Log().Add("2 - After me the world will be a better place!")
//fmt.Println(c.log) //fmt.Println(c.log)
fmt.Println(c.Log()) fmt.Println(c.Log())
} }
func (l *Log) Add(s string) { func (l *Log) Add(s string) {
l.msg += "\n" + s l.msg += "\n" + s
} }
func (l *Log) String() string { func (l *Log) String() string {
return l.msg return l.msg
} }
func (c *Customer) Log() *Log { func (c *Customer) Log() *Log {
return c.log return c.log
} }
/* Output:
1 - Yes we can! /* Output:
2 - After me the world will be a better place! 1 - Yes we can!
*/ 2 - After me the world will be a better place!
*/

View File

@@ -1,38 +1,38 @@
package main package main
import ( import (
"fmt" "fmt"
) )
type Log struct { type Log struct {
msg string msg string
} }
type Customer struct { type Customer struct {
Name string Name string
Log Log
} }
func main() { func main() {
c := &Customer{"Barak Obama", Log{"1 - Yes we can!"}} c := &Customer{"Barak Obama", Log{"1 - Yes we can!"}}
c.Add("2 - After me the world will be a better place!") c.Add("2 - After me the world will be a better place!")
fmt.Println(c) fmt.Println(c)
} }
func (l *Log) Add(s string) { func (l *Log) Add(s string) {
l.msg += "\n" + s l.msg += "\n" + s
} }
func (c *Customer) String() string { func (c *Customer) String() string {
return c.Name + "\nLog:" + fmt.Sprintln(c.Log) return c.Name + "\nLog:" + fmt.Sprintln(c.Log)
} }
func (l *Log) String() string { func (l *Log) String() string {
return l.msg return l.msg
} }
/* Output: /* Output:
Barak Obama Barak Obama
Log:{1 - Yes we can! Log:{1 - Yes we can!
2 - After me the world will be a better place!} 2 - After me the world will be a better place!}
*/ */

View File

@@ -1,18 +1,18 @@
package main package main
import "fmt" import "fmt"
type A struct { type A struct {
ax, ay int ax, ay int
} }
type B struct { type B struct {
A A
bx, by float32 bx, by float32
} }
func main() { func main() {
b := B{A{1, 2}, 3.0, 4.0} b := B{A{1, 2}, 3.0, 4.0}
fmt.Println(b.ax, b.ay, b.bx, b.by) fmt.Println(b.ax, b.ay, b.bx, b.by)
fmt.Println(b.A) fmt.Println(b.A)
} }

View File

@@ -1,16 +1,17 @@
package main package main
import ( import (
"fmt" "./struct_pack/structPack"
"./struct_pack/structPack" "fmt"
) )
func main() { func main() {
struct1 := new(structPack.ExpStruct) struct1 := new(structPack.ExpStruct)
struct1.Mi1 = 10 struct1.Mi1 = 10
struct1.Mf1 = 16. struct1.Mf1 = 16.
fmt.Printf("Mi1 = %d\n", struct1.Mi1) fmt.Printf("Mi1 = %d\n", struct1.Mi1)
fmt.Printf("Mf1 = %f\n", struct1.Mf1) fmt.Printf("Mf1 = %f\n", struct1.Mf1)
} }
// Mi1 = 10
// Mf1 = 16.000000 // Mi1 = 10
// Mf1 = 16.000000

View File

@@ -1,29 +1,29 @@
package main package main
import "fmt" import "fmt"
type TwoInts struct { type TwoInts struct {
a int a int
b int b int
} }
func main() { func main() {
two1 := new(TwoInts) two1 := new(TwoInts)
two1.a = 12 two1.a = 12
two1.b = 10 two1.b = 10
fmt.Printf("The sum is: %d\n", two1.AddThem()) fmt.Printf("The sum is: %d\n", two1.AddThem())
fmt.Printf("Add them to the param: %d\n", two1.AddToParam(20)) fmt.Printf("Add them to the param: %d\n", two1.AddToParam(20))
// literal: // literal:
two2 := TwoInts{3, 4} two2 := TwoInts{3, 4}
fmt.Printf("The sum is: %d\n", two2.AddThem()) fmt.Printf("The sum is: %d\n", two2.AddThem())
} }
func (tn *TwoInts) AddThem() int { func (tn *TwoInts) AddThem() int {
return tn.a + tn.b return tn.a + tn.b
} }
func (tn *TwoInts) AddToParam(param int) int { func (tn *TwoInts) AddToParam(param int) int {
return tn.a + tn.b + param return tn.a + tn.b + param
} }

View File

@@ -1,16 +1,16 @@
package main package main
import "fmt" import "fmt"
type IntVector []int type IntVector []int
func (v IntVector) Sum() (s int) { func (v IntVector) Sum() (s int) {
for _, x := range v { for _, x := range v {
s += x s += x
} }
return return
} }
func main() { func main() {
fmt.Println(IntVector{1, 2, 3}.Sum()) // Output: 6 fmt.Println(IntVector{1, 2, 3}.Sum()) // Output: 6
} }

View File

@@ -1,24 +1,24 @@
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
) )
type Point struct { type Point struct {
x, y float64 x, y float64
} }
func (p *Point) Abs() float64 { func (p *Point) Abs() float64 {
return math.Sqrt(p.x*p.x + p.y*p.y) return math.Sqrt(p.x*p.x + p.y*p.y)
} }
type NamedPoint struct { type NamedPoint struct {
Point Point
name string name string
} }
func main() { func main() {
n := &NamedPoint{Point{3, 4}, "Pythagoras"} n := &NamedPoint{Point{3, 4}, "Pythagoras"}
fmt.Println(n.Abs()) // prints 5 fmt.Println(n.Abs()) // prints 5
} }

View File

@@ -1,28 +1,28 @@
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
) )
type Point struct { type Point struct {
x, y float64 x, y float64
} }
func (p *Point) Abs() float64 { func (p *Point) Abs() float64 {
return math.Sqrt(p.x*p.x + p.y*p.y) return math.Sqrt(p.x*p.x + p.y*p.y)
} }
type NamedPoint struct { type NamedPoint struct {
Point Point
name string name string
} }
func (n *NamedPoint) Abs() float64 { func (n *NamedPoint) Abs() float64 {
return n.Point.Abs() * 100. return n.Point.Abs() * 100.
} }
func main() { func main() {
n := &NamedPoint{Point{3, 4}, "Pythagoras"} n := &NamedPoint{Point{3, 4}, "Pythagoras"}
fmt.Println(n.Abs()) // prints 500 fmt.Println(n.Abs()) // prints 500
} }

View File

@@ -1,25 +1,26 @@
// method_on_time.go // method_on_time.go
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
type myTime struct { type myTime struct {
time.Time //anonymous field time.Time //anonymous field
} }
func (t myTime) first3Chars() string { func (t myTime) first3Chars() string {
return t.Time.String()[0:3] return t.Time.String()[0:3]
} }
func main() { func main() {
m := myTime{time.Now()} m := myTime{time.Now()}
fmt.Println("Full time now:", m.String()) //calling existing String method on anonymous Time field fmt.Println("Full time now:", m.String()) //calling existing String method on anonymous Time field
fmt.Println("First 3 chars:", m.first3Chars()) //calling myTime.first3Chars fmt.Println("First 3 chars:", m.first3Chars()) //calling myTime.first3Chars
} }
/* Output:
Full time now: Mon Oct 24 15:34:54 Romance Daylight Time 2011 /* Output:
First 3 chars: Mon Full time now: Mon Oct 24 15:34:54 Romance Daylight Time 2011
*/ First 3 chars: Mon
*/

View File

@@ -1,27 +1,25 @@
package main package main
import ( import (
"fmt" "fmt"
"strconv" "strconv"
) )
type TwoInts struct { type TwoInts struct {
a int a int
b int b int
} }
func main() { func main() {
two1 := new(TwoInts) two1 := new(TwoInts)
two1.a = 12 two1.a = 12
two1.b = 10 two1.b = 10
fmt.Printf("two1 is: %v\n", two1) fmt.Printf("two1 is: %v\n", two1)
fmt.Println("two1 is:", two1) fmt.Println("two1 is:", two1)
fmt.Printf("two1 is: %T\n", two1) fmt.Printf("two1 is: %T\n", two1)
fmt.Printf("two1 is: %#v\n", two1) fmt.Printf("two1 is: %#v\n", two1)
} }
func (tn *TwoInts) String() string { func (tn *TwoInts) String() string {
return "(" + strconv.Itoa(tn.a) + " / " + strconv.Itoa(tn.b) + ")" return "(" + strconv.Itoa(tn.a) + " / " + strconv.Itoa(tn.b) + ")"
} }

View File

@@ -1,22 +1,23 @@
// methodset1.go // methodset1.go
package main package main
import ( import (
"fmt" "fmt"
) )
type List []int type List []int
func (l List) Len() int { return len(l) }
func (l *List) Append(val int) { *l = append(*l, val) } func (l List) Len() int { return len(l) }
func (l *List) Append(val int) { *l = append(*l, val) }
func main() {
// A bare value func main() {
var lst List // A bare value
lst.Append(1) var lst List
fmt.Printf("%v (len: %d)\n", lst, lst.Len()) // [1] (len: 1) lst.Append(1)
fmt.Printf("%v (len: %d)\n", lst, lst.Len()) // [1] (len: 1)
// A pointer value
plst := new(List) // A pointer value
plst.Append(2) plst := new(List)
fmt.Printf("%v (len: %d)\n", plst, lst.Len()) // &[2] (len: 1) plst.Append(2)
} fmt.Printf("%v (len: %d)\n", plst, lst.Len()) // &[2] (len: 1)
}

View File

@@ -1,34 +1,35 @@
// mult_inheritance.go // mult_inheritance.go
package main package main
import "fmt" import "fmt"
type Camera struct { } type Camera struct{}
func (c *Camera) TakeAPicture() string { func (c *Camera) TakeAPicture() string {
return "Click" return "Click"
} }
type Phone struct { } type Phone struct{}
func (p *Phone ) Call() string { func (p *Phone) Call() string {
return "Ring Ring" return "Ring Ring"
} }
// multiple inheritance // multiple inheritance
type CameraPhone struct { type CameraPhone struct {
Camera Camera
Phone Phone
} }
func main() { func main() {
cp := new(CameraPhone) cp := new(CameraPhone)
fmt.Println("Our new CameraPhone exhibits multiple behaviors ...") fmt.Println("Our new CameraPhone exhibits multiple behaviors ...")
fmt.Println("It exhibits behavior of a Camera: ", cp.TakeAPicture()) fmt.Println("It exhibits behavior of a Camera: ", cp.TakeAPicture())
fmt.Println("It works like a Phone too: ", cp.Call()) fmt.Println("It works like a Phone too: ", cp.Call())
} }
/* Output:
Our new CameraPhone exhibits multiple behaviors ... /* Output:
It exhibits behavior of a Camera: Click Our new CameraPhone exhibits multiple behaviors ...
It works like a Phone too: Ring Ring It exhibits behavior of a Camera: Click
*/ It works like a Phone too: Ring Ring
*/

View File

@@ -1,27 +1,27 @@
// annoy1.go // annoy1.go
package main package main
type Foo map[string]string type Foo map[string]string
type Bar struct { type Bar struct {
thingOne string thingOne string
thingTwo int thingTwo int
} }
func main() { func main() {
// OK: // OK:
y := new(Bar) y := new(Bar)
(*y).thingOne = "hello" (*y).thingOne = "hello"
(*y).thingTwo = 1 (*y).thingTwo = 1
// not OK: // not OK:
z := make(Bar) // compile error: cannot make type Bar z := make(Bar) // compile error: cannot make type Bar
z.thingOne = "hello" z.thingOne = "hello"
z.thingTwo = 1 z.thingTwo = 1
// OK: // OK:
x := make(Foo) x := make(Foo)
x["x"] = "goodbye" x["x"] = "goodbye"
x["y"] = "world" x["y"] = "world"
// not OK: // not OK:
u := new(Foo) u := new(Foo)
(*u)["x"] = "goodbye" // !! panic !!: runtime error: assignment to entry in nil map (*u)["x"] = "goodbye" // !! panic !!: runtime error: assignment to entry in nil map
(*u)["y"] = "world" (*u)["y"] = "world"
} }

View File

@@ -1,41 +1,42 @@
package main package main
import ( import (
"fmt" "fmt"
"strings" "strings"
) )
type Person struct { type Person struct {
firstName string firstName string
lastName string lastName string
} }
func upPerson (p *Person) { func upPerson(p *Person) {
p.firstName = strings.ToUpper(p.firstName) p.firstName = strings.ToUpper(p.firstName)
p.lastName = strings.ToUpper(p.lastName) p.lastName = strings.ToUpper(p.lastName)
} }
func main() { func main() {
// 1- struct as a value type: // 1- struct as a value type:
var pers1 Person var pers1 Person
pers1.firstName = "Chris" pers1.firstName = "Chris"
pers1.lastName = "Woodward" pers1.lastName = "Woodward"
upPerson(&pers1) upPerson(&pers1)
fmt.Printf("The name of the person is %s %s\n", pers1.firstName, pers1.lastName) fmt.Printf("The name of the person is %s %s\n", pers1.firstName, pers1.lastName)
// 2 - struct as a pointer: // 2 - struct as a pointer:
pers2 := new(Person) pers2 := new(Person)
pers2.firstName = "Chris" pers2.firstName = "Chris"
pers2.lastName = "Woodward" pers2.lastName = "Woodward"
(*pers2).lastName = "Woodward" (*pers2).lastName = "Woodward"
upPerson(pers2) upPerson(pers2)
fmt.Printf("The name of the person is %s %s\n", pers2.firstName, pers2.lastName) fmt.Printf("The name of the person is %s %s\n", pers2.firstName, pers2.lastName)
// 3 - struct as a literal: // 3 - struct as a literal:
pers3 := &Person{"Chris","Woodward"} pers3 := &Person{"Chris", "Woodward"}
upPerson(pers3) upPerson(pers3)
fmt.Printf("The name of the person is %s %s\n", pers3.firstName, pers3.lastName) fmt.Printf("The name of the person is %s %s\n", pers3.firstName, pers3.lastName)
} }
/* Output:
The name of the person is CHRIS WOODWARD /* Output:
The name of the person is CHRIS WOODWARD The name of the person is CHRIS WOODWARD
The name of the person is CHRIS WOODWARD The name of the person is CHRIS WOODWARD
*/ The name of the person is CHRIS WOODWARD
*/

View File

@@ -1,17 +1,14 @@
package person package person
type Person struct { type Person struct {
firstName string firstName string
lastName string lastName string
} }
func (p *Person) FirstName() string { func (p *Person) FirstName() string {
return p.firstName return p.firstName
} }
func (p *Person) SetFirstName(newName string) { func (p *Person) SetFirstName(newName string) {
p.firstName = newName p.firstName = newName
} }

View File

@@ -1,28 +1,29 @@
// pointer_value.go // pointer_value.go
package main package main
import ( import (
"fmt" "fmt"
) )
type B struct { type B struct {
thing int thing int
} }
func (b *B) change() { b.thing = 1 } func (b *B) change() { b.thing = 1 }
func (b B) write() string { return fmt.Sprint(b) } func (b B) write() string { return fmt.Sprint(b) }
func main() { func main() {
var b1 B // b1 is value var b1 B // b1 is value
b1.change() b1.change()
fmt.Println(b1.write()) fmt.Println(b1.write())
b2 := new(B) // b2 is pointer b2 := new(B) // b2 is pointer
b2.change() b2.change()
fmt.Println(b2.write()) fmt.Println(b2.write())
} }
/* Output:
{1} /* Output:
{1} {1}
*/ {1}
*/

View File

@@ -1,24 +1,25 @@
// struct_conversions.go // struct_conversions.go
package main package main
import ( import (
"fmt" "fmt"
) )
type number struct { type number struct {
f float32 f float32
} }
type nr number // alias type type nr number // alias type
func main() { func main() {
a := number{5.0} a := number{5.0}
b := nr{5.0} b := nr{5.0}
// var i float32 = b // compile-error: cannot use b (type nr) as type float32 in assignment // var i float32 = b // compile-error: cannot use b (type nr) as type float32 in assignment
// var i = float32(b) // compile-error: cannot convert b (type nr) to type float32 // var i = float32(b) // compile-error: cannot convert b (type nr) to type float32
// var c number = b // compile-error: cannot use b (type nr) as type number in assignment // var c number = b // compile-error: cannot use b (type nr) as type number in assignment
// needs a conversion: // needs a conversion:
var c = number(b) var c = number(b)
fmt.Println(a, b, c) fmt.Println(a, b, c)
} }
// output: {5} {5} {5}
// output: {5} {5} {5}

View File

@@ -1,6 +1,6 @@
package structPack package structPack
type ExpStruct struct { type ExpStruct struct {
Mi1 int Mi1 int
Mf1 float32 Mf1 float32
} }

View File

@@ -1,30 +1,31 @@
package main package main
import ( import (
"fmt" "fmt"
"reflect" "reflect"
) )
type TagType struct { // tags type TagType struct { // tags
field1 bool "An important answer" field1 bool "An important answer"
field2 string "The name of the thing" field2 string "The name of the thing"
field3 int "How much there are" field3 int "How much there are"
} }
func main() { func main() {
tt := TagType{true, "Barak Obama", 1} tt := TagType{true, "Barak Obama", 1}
for i:= 0; i < 3; i++ { for i := 0; i < 3; i++ {
refTag(tt, i) refTag(tt, i)
} }
} }
func refTag(tt TagType, ix int) { func refTag(tt TagType, ix int) {
ttType := reflect.TypeOf(tt) ttType := reflect.TypeOf(tt)
ixField := ttType.Field(ix) ixField := ttType.Field(ix)
fmt.Printf("%v\n", ixField.Tag) fmt.Printf("%v\n", ixField.Tag)
} }
/* Output:
An important answer /* Output:
The name of the thing An important answer
How much there are The name of the thing
*/ How much there are
*/

View File

@@ -1,34 +1,34 @@
package main package main
import "fmt" import "fmt"
type innerS struct { type innerS struct {
in1 int in1 int
in2 int in2 int
} }
type outerS struct { type outerS struct {
b int b int
c float32 c float32
int // anonymous field int // anonymous field
innerS // anonymous field innerS // anonymous field
} }
func main() { func main() {
outer := new(outerS) outer := new(outerS)
outer.b = 6 outer.b = 6
outer.c = 7.5 outer.c = 7.5
outer.int = 60 outer.int = 60
outer.in1 = 5 outer.in1 = 5
outer.in2 = 10 outer.in2 = 10
fmt.Printf("outer.b is: %d\n", outer.b) fmt.Printf("outer.b is: %d\n", outer.b)
fmt.Printf("outer.c is: %f\n", outer.c) fmt.Printf("outer.c is: %f\n", outer.c)
fmt.Printf("outer.int is: %d\n", outer.int) fmt.Printf("outer.int is: %d\n", outer.int)
fmt.Printf("outer.in1 is: %d\n", outer.in1) fmt.Printf("outer.in1 is: %d\n", outer.in1)
fmt.Printf("outer.in2 is: %d\n", outer.in2) fmt.Printf("outer.in2 is: %d\n", outer.in2)
// with a struct-literal: // with a struct-literal:
outer2 := outerS{6, 7.5, 60, innerS{5, 10}} outer2 := outerS{6, 7.5, 60, innerS{5, 10}}
fmt.Println("outer2 is: ", outer2) fmt.Println("outer2 is: ", outer2)
} }

View File

@@ -1,23 +1,23 @@
package main package main
import "fmt" import "fmt"
type struct1 struct { type struct1 struct {
i1 int i1 int
f1 float32 f1 float32
str string str string
} }
func main() { func main() {
// var ms *struct1 = new(struct1) // var ms *struct1 = new(struct1)
// better: // better:
ms := new(struct1) ms := new(struct1)
ms.i1 = 10 ms.i1 = 10
ms.f1 = 15.5 ms.f1 = 15.5
ms.str = "Chris" ms.str = "Chris"
// ms := &struct1{10, 15.5, "Chris"} // ms := &struct1{10, 15.5, "Chris"}
fmt.Printf("The int is: %d\n", ms.i1) fmt.Printf("The int is: %d\n", ms.i1)
fmt.Printf("The float is: %f\n", ms.f1) fmt.Printf("The float is: %f\n", ms.f1)
fmt.Printf("The string is: %s\n", ms.str) fmt.Printf("The string is: %s\n", ms.str)
fmt.Println(ms) // output: &{10 15.5 Chris} fmt.Println(ms) // output: &{10 15.5 Chris}
} }

View File

@@ -1,14 +1,14 @@
package main package main
import ( import (
"fmt" "./person"
"./person" "fmt"
) )
func main() { func main() {
p := new(person.Person) p := new(person.Person)
// error: p.firstName undefined (cannot refer to unexported field or method firstName) // error: p.firstName undefined (cannot refer to unexported field or method firstName)
// p.firstName = "Eric" // p.firstName = "Eric"
p.SetFirstName("Eric") p.SetFirstName("Eric")
fmt.Println(p.FirstName()) // Output: Eric fmt.Println(p.FirstName()) // Output: Eric
} }

View File

@@ -1,95 +1,94 @@
// cars.go // cars.go
package main package main
import ( import (
"fmt" "fmt"
) )
type Any interface{}
type Any interface{} type Car struct {
type Car struct { Model string
Model string Manufacturer string
Manufacturer string BuildYear int
BuildYear int // ...
// ... }
} type Cars []*Car
type Cars []*Car
func main() {
func main() { // make some cars:
// make some cars: ford := &Car{"Fiesta", "Ford", 2008}
ford := &Car{"Fiesta","Ford", 2008} bmw := &Car{"XL 450", "BMW", 2011}
bmw := &Car{"XL 450", "BMW", 2011} merc := &Car{"D600", "Mercedes", 2009}
merc := &Car{"D600", "Mercedes", 2009} bmw2 := &Car{"X 800", "BMW", 2008}
bmw2 := &Car{"X 800", "BMW", 2008} // query:
// query: allCars := Cars([]*Car{ford, bmw, merc, bmw2})
allCars := Cars([]*Car{ford, bmw, merc, bmw2}) allNewBMWs := allCars.FindAll(func(car *Car) bool {
allNewBMWs := allCars.FindAll(func(car *Car) bool { return (car.Manufacturer == "BMW") && (car.BuildYear > 2010)
return (car.Manufacturer == "BMW") && (car.BuildYear > 2010) })
}) fmt.Println("AllCars: ", allCars)
fmt.Println("AllCars: ", allCars) fmt.Println("New BMWs: ", allNewBMWs)
fmt.Println("New BMWs: ", allNewBMWs) //
// manufacturers := []string{"Ford", "Aston Martin", "Land Rover", "BMW", "Jaguar"}
manufacturers := []string{"Ford", "Aston Martin", "Land Rover", "BMW", "Jaguar"} sortedAppender, sortedCars := MakeSortedAppender(manufacturers)
sortedAppender, sortedCars := MakeSortedAppender(manufacturers) allCars.Process(sortedAppender)
allCars.Process(sortedAppender) fmt.Println("Map sortedCars: ", sortedCars)
fmt.Println("Map sortedCars: ", sortedCars) BMWCount := len(sortedCars["BMW"])
BMWCount := len(sortedCars["BMW"]) fmt.Println("We have ", BMWCount, " BMWs")
fmt.Println("We have ", BMWCount, " BMWs") }
}
// Process all cars with the given function f:
// Process all cars with the given function f: func (cs Cars) Process(f func(car *Car)) {
func (cs Cars) Process(f func(car *Car)) { for _, c := range cs {
for _, c := range cs { f(c)
f(c) }
} }
}
// Find all cars matching a given criteria.
// Find all cars matching a given criteria. func (cs Cars) FindAll(f func(car *Car) bool) Cars {
func (cs Cars) FindAll(f func(car *Car) bool) Cars { cars := make([]*Car, 0)
cars := make([]*Car, 0)
cs.Process(func(c *Car) {
cs.Process(func(c *Car) { if f(c) {
if f(c) { cars = append(cars, c)
cars = append(cars, c) }
} })
}) return cars
return cars }
}
// Process cars and create new data.
// Process cars and create new data. func (cs Cars) Map(f func(car *Car) Any) []Any {
func (cs Cars) Map(f func(car *Car) Any) []Any { result := make([]Any, 0)
result := make([]Any, 0) ix := 0
ix := 0 cs.Process(func(c *Car) {
cs.Process(func(c *Car) { result[ix] = f(c)
result[ix] = f(c) ix++
ix++ })
}) return result
return result }
}
func MakeSortedAppender(manufacturers []string) (func(car *Car), map[string]Cars) {
func MakeSortedAppender(manufacturers []string) (func(car *Car), map[string]Cars) { // Prepare maps of sorted cars.
// Prepare maps of sorted cars. sortedCars := make(map[string]Cars)
sortedCars := make(map[string]Cars)
for _, m := range manufacturers {
for _, m := range manufacturers { sortedCars[m] = make([]*Car, 0)
sortedCars[m] = make([]*Car, 0) }
} sortedCars["Default"] = make([]*Car, 0)
sortedCars["Default"] = make([]*Car, 0)
// Prepare appender function:
// Prepare appender function: appender := func(c *Car) {
appender := func(c *Car) { if _, ok := sortedCars[c.Manufacturer]; ok {
if _, ok := sortedCars[c.Manufacturer]; ok { sortedCars[c.Manufacturer] = append(sortedCars[c.Manufacturer], c)
sortedCars[c.Manufacturer] = append(sortedCars[c.Manufacturer], c) } else {
} else { sortedCars["Default"] = append(sortedCars["Default"], c)
sortedCars["Default"] = append(sortedCars["Default"], c) }
} }
} return appender, sortedCars
return appender, sortedCars }
}
/* Output:
/* Output: AllCars: [0xf8400038a0 0xf840003bd0 0xf840003ba0 0xf840003b70]
AllCars: [0xf8400038a0 0xf840003bd0 0xf840003ba0 0xf840003b70] New BMWs: [0xf840003bd0]
New BMWs: [0xf840003bd0] Map sortedCars: map[Default:[0xf840003ba0] Jaguar:[] Land Rover:[] BMW:[0xf840003bd0 0xf840003b70] Aston Martin:[] Ford:[0xf8400038a0]]
Map sortedCars: map[Default:[0xf840003ba0] Jaguar:[] Land Rover:[] BMW:[0xf840003bd0 0xf840003b70] Aston Martin:[] Ford:[0xf8400038a0]] We have 2 BMWs
We have 2 BMWs */
*/

View File

@@ -1,32 +1,32 @@
package main package main
import "fmt" import "fmt"
type IDuck interface { type IDuck interface {
Quack() Quack()
Walk() Walk()
} }
func DuckDance(duck IDuck) { func DuckDance(duck IDuck) {
for i := 1; i <= 3; i++ { for i := 1; i <= 3; i++ {
duck.Quack() duck.Quack()
duck.Walk() duck.Walk()
} }
} }
type Bird struct { type Bird struct {
// ... // ...
} }
func (b *Bird) Quack() { func (b *Bird) Quack() {
fmt.Println("I am quacking!") fmt.Println("I am quacking!")
} }
func (b *Bird) Walk() { func (b *Bird) Walk() {
fmt.Println("I am walking!") fmt.Println("I am walking!")
} }
func main() { func main() {
b := new(Bird) b := new(Bird)
DuckDance(b) DuckDance(b)
} }

View File

@@ -1,38 +1,38 @@
package main package main
import "fmt" import "fmt"
var i = 5 var i = 5
var str = "ABC" var str = "ABC"
type Person struct { type Person struct {
name string name string
age int age int
} }
type Any interface{} type Any interface{}
func main() { func main() {
var val Any var val Any
val = 5 val = 5
fmt.Printf("val has the value: %v\n", val) fmt.Printf("val has the value: %v\n", val)
val = str val = str
fmt.Printf("val has the value: %v\n", val) fmt.Printf("val has the value: %v\n", val)
pers1 := new(Person) pers1 := new(Person)
pers1.name = "Rob Pike" pers1.name = "Rob Pike"
pers1.age = 55 pers1.age = 55
val = pers1 val = pers1
fmt.Printf("val has the value: %v\n", val) fmt.Printf("val has the value: %v\n", val)
switch t := val.(type) { switch t := val.(type) {
case int: case int:
fmt.Printf("Type int %T\n", t) fmt.Printf("Type int %T\n", t)
case string: case string:
fmt.Printf("Type string %T\n", t) fmt.Printf("Type string %T\n", t)
case bool: case bool:
fmt.Printf("Type boolean %T\n", t) fmt.Printf("Type boolean %T\n", t)
case *Person: case *Person:
fmt.Printf("Type pointer to Person %T\n", *t) fmt.Printf("Type pointer to Person %T\n", *t)
default: default:
fmt.Printf("Unexpected type %T", t) fmt.Printf("Unexpected type %T", t)
} }
} }

View File

@@ -29,4 +29,5 @@ func TypeSwitch() {
func main() { func main() {
TypeSwitch() TypeSwitch()
} }
// Output: any hello is a special String! // Output: any hello is a special String!

View File

@@ -1,30 +1,31 @@
package main package main
import "fmt" import "fmt"
type Shaper interface { type Shaper interface {
Area() float32 Area() float32
// Perimeter() float32 // Perimeter() float32
} }
type Square struct { type Square struct {
side float32 side float32
} }
func (sq *Square) Area() float32 { func (sq *Square) Area() float32 {
return sq.side * sq.side return sq.side * sq.side
} }
func main() { func main() {
sq1 := new(Square) sq1 := new(Square)
sq1.side = 5 sq1.side = 5
// var areaIntf Shaper // var areaIntf Shaper
// areaIntf = sq1 // areaIntf = sq1
// shorter, without separate declaration: // shorter, without separate declaration:
// areaIntf := Shaper(sq1) // areaIntf := Shaper(sq1)
// or even: // or even:
areaIntf := sq1 areaIntf := sq1
fmt.Printf("The square has area: %f\n", areaIntf.Area()) fmt.Printf("The square has area: %f\n", areaIntf.Area())
} }
// The square has area: 25.000000
// The square has area: 25.000000

View File

@@ -1,45 +1,43 @@
// interfaces_poly.go // interfaces_poly.go
package main package main
import "fmt" import "fmt"
type Shaper interface { type Shaper interface {
Area() float32 Area() float32
} }
type Square struct { type Square struct {
side float32 side float32
} }
func (sq *Square) Area() float32 { func (sq *Square) Area() float32 {
return sq.side * sq.side return sq.side * sq.side
} }
type Rectangle struct { type Rectangle struct {
length, width float32 length, width float32
} }
func (r Rectangle) Area() float32 { func (r Rectangle) Area() float32 {
return r.length * r.width return r.length * r.width
} }
func main() { func main() {
r := Rectangle{5, 3} // Area() of Rectangle needs a value r := Rectangle{5, 3} // Area() of Rectangle needs a value
q := &Square{5} // Area() of Square needs a pointer q := &Square{5} // Area() of Square needs a pointer
shapes := []Shaper{r, q} shapes := []Shaper{r, q}
fmt.Println("Looping through shapes for area ...") fmt.Println("Looping through shapes for area ...")
for n, _ := range shapes { for n := range shapes {
fmt.Println("Shape details: ", shapes[n]) fmt.Println("Shape details: ", shapes[n])
fmt.Println("Area of this shape is: ", shapes[n].Area()) fmt.Println("Area of this shape is: ", shapes[n].Area())
} }
} }
/* Output:
Looping through shapes for area ... /* Output:
Shape details: {5 3} Looping through shapes for area ...
Area of this shape is: 15 Shape details: {5 3}
Shape details: &{5} Area of this shape is: 15
Area of this shape is: 25 Shape details: &{5}
*/ Area of this shape is: 25
*/

View File

@@ -1,48 +1,49 @@
// methodset2.go // methodset2.go
package main package main
import ( import (
"fmt" "fmt"
) )
type List []int type List []int
func (l List) Len() int { return len(l) }
func (l *List) Append(val int) { *l = append(*l, val) } func (l List) Len() int { return len(l) }
func (l *List) Append(val int) { *l = append(*l, val) }
type Appender interface {
Append(int) type Appender interface {
} Append(int)
}
func CountInto(a Appender, start, end int) {
for i := start; i <= end; i++ { func CountInto(a Appender, start, end int) {
a.Append(i) for i := start; i <= end; i++ {
} a.Append(i)
} }
}
type Lener interface {
Len() int type Lener interface {
} Len() int
}
func LongEnough(l Lener) bool {
return l.Len()*10 > 42 func LongEnough(l Lener) bool {
} return l.Len()*10 > 42
}
func main() {
// A bare value func main() {
var lst List // A bare value
// compiler error: var lst List
// cannot use lst (type List) as type Appender in function argument: // compiler error:
// List does not implement Appender (Append method requires pointer receiver) // cannot use lst (type List) as type Appender in function argument:
// CountInto(lst, 1, 10) // INVALID: Append has a pointer receiver // List does not implement Appender (Append method requires pointer receiver)
// CountInto(lst, 1, 10) // INVALID: Append has a pointer receiver
if LongEnough(lst) { // VALID: Identical receiver type
fmt.Printf(" - lst is long enough") if LongEnough(lst) { // VALID: Identical receiver type
} fmt.Printf(" - lst is long enough")
}
// A pointer value
plst := new(List) // A pointer value
CountInto(plst, 1, 10) // VALID: Identical receiver type plst := new(List)
if LongEnough(plst) { // VALID: a *List can be dereferenced for the receiver CountInto(plst, 1, 10) // VALID: Identical receiver type
fmt.Printf(" - plst is long enough") // - plst is long enoug if LongEnough(plst) { // VALID: a *List can be dereferenced for the receiver
} fmt.Printf(" - plst is long enough") // - plst is long enoug
} }
}

View File

@@ -1,65 +1,66 @@
//multi_interfaces_poly.go //multi_interfaces_poly.go
package main package main
import "fmt" import "fmt"
type Shaper interface { type Shaper interface {
Area() float32 Area() float32
} }
type TopologicalGenus interface { type TopologicalGenus interface {
Rank() int Rank() int
} }
type Square struct { type Square struct {
side float32 side float32
} }
func (sq *Square) Area() float32 { func (sq *Square) Area() float32 {
return sq.side * sq.side return sq.side * sq.side
} }
func (sq *Square) Rank() int { func (sq *Square) Rank() int {
return 1 return 1
} }
type Rectangle struct { type Rectangle struct {
length, width float32 length, width float32
} }
func (r Rectangle) Area() float32 { func (r Rectangle) Area() float32 {
return r.length * r.width return r.length * r.width
} }
func (r Rectangle) Rank() int { func (r Rectangle) Rank() int {
return 2 return 2
} }
func main() { func main() {
r := Rectangle{5, 3} // Area() of Rectangle needs a value r := Rectangle{5, 3} // Area() of Rectangle needs a value
q := &Square{5} // Area() of Square needs a pointer q := &Square{5} // Area() of Square needs a pointer
shapes := []Shaper{r, q} shapes := []Shaper{r, q}
fmt.Println("Looping through shapes for area ...") fmt.Println("Looping through shapes for area ...")
for n, _ := range shapes { for n := range shapes {
fmt.Println("Shape details: ", shapes[n]) fmt.Println("Shape details: ", shapes[n])
fmt.Println("Area of this shape is: ", shapes[n].Area()) fmt.Println("Area of this shape is: ", shapes[n].Area())
} }
topgen := []TopologicalGenus{r, q} topgen := []TopologicalGenus{r, q}
fmt.Println("Looping through topgen for rank ...") fmt.Println("Looping through topgen for rank ...")
for n, _ := range topgen { for n := range topgen {
fmt.Println("Shape details: ", topgen[n]) fmt.Println("Shape details: ", topgen[n])
fmt.Println("Topological Genus of this shape is: ", topgen[n].Rank()) fmt.Println("Topological Genus of this shape is: ", topgen[n].Rank())
} }
} }
/* Output:
Looping through shapes for area ... /* Output:
Shape details: {5 3} Looping through shapes for area ...
Area of this shape is: 15 Shape details: {5 3}
Shape details: &{5} Area of this shape is: 15
Area of this shape is: 25 Shape details: &{5}
Looping through topgen for rank ... Area of this shape is: 25
Shape details: {5 3} Looping through topgen for rank ...
Topological Genus of this shape is: 2 Shape details: {5 3}
Shape details: &{5} Topological Genus of this shape is: 2
Topological Genus of this shape is: 1 Shape details: &{5}
*/ Topological Genus of this shape is: 1
*/

View File

@@ -1,31 +1,31 @@
// node_structures.go // node_structures.go
package main package main
import "fmt" import "fmt"
type Node struct { type Node struct {
le *Node le *Node
data interface{} data interface{}
ri *Node ri *Node
} }
func NewNode(left, right *Node) *Node { func NewNode(left, right *Node) *Node {
return &Node{left, nil, right} return &Node{left, nil, right}
} }
func (n *Node) SetData(data interface{}) { func (n *Node) SetData(data interface{}) {
n.data = data n.data = data
} }
func main() { func main() {
root := NewNode(nil,nil) root := NewNode(nil, nil)
root.SetData("root node") root.SetData("root node")
// make child (leaf) nodes: // make child (leaf) nodes:
a := NewNode(nil,nil) a := NewNode(nil, nil)
a.SetData("left node") a.SetData("left node")
b := NewNode(nil,nil) b := NewNode(nil, nil)
b.SetData("right node") b.SetData("right node")
root.le = a root.le = a
root.ri = b root.ri = b
fmt.Printf("%v\n", root) // Output: &{0x125275f0 root node 0x125275e0} fmt.Printf("%v\n", root) // Output: &{0x125275f0 root node 0x125275e0}
} }

View File

@@ -1,43 +1,50 @@
// print.go // print.go
package main package main
import ( import (
"os" "os"
"strconv" "strconv"
) )
type Stringer interface { type Stringer interface {
String() string String() string
} }
type Celsius float64 type Celsius float64
func (c Celsius) String() string { func (c Celsius) String() string {
return strconv.FormatFloat(float64(c),'f', 1, 64) + " °C" return strconv.FormatFloat(float64(c), 'f', 1, 64) + " °C"
} }
type Day int type Day int
var dayName = []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"} var dayName = []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
func (day Day) String() string { func (day Day) String() string {
return dayName[day] return dayName[day]
} }
func print(args ...interface{}) { func print(args ...interface{}) {
for i, arg := range args { for i, arg := range args {
if i > 0 {os.Stdout.WriteString(" ")} if i > 0 {
switch a := arg.(type) { // type switch os.Stdout.WriteString(" ")
case Stringer: os.Stdout.WriteString(a.String()) }
case int: os.Stdout.WriteString(strconv.Itoa(a)) switch a := arg.(type) { // type switch
case string: os.Stdout.WriteString(a) case Stringer:
// more types os.Stdout.WriteString(a.String())
default: os.Stdout.WriteString("???") case int:
} os.Stdout.WriteString(strconv.Itoa(a))
} case string:
} os.Stdout.WriteString(a)
// more types
func main() { default:
print(Day(1), "was", Celsius(18.36)) // Tuesday was 18.4 °C os.Stdout.WriteString("???")
} }
// Tuesday was 18.4 °C }
}
func main() {
print(Day(1), "was", Celsius(18.36)) // Tuesday was 18.4 °C
}
// Tuesday was 18.4 °C

View File

@@ -1,32 +1,33 @@
// reflect1.go // reflect1.go
// blog: Laws of Reflection // blog: Laws of Reflection
package main package main
import ( import (
"fmt" "fmt"
"reflect" "reflect"
) )
func main() { func main() {
var x float64 = 3.4 var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x)) fmt.Println("type:", reflect.TypeOf(x))
v := reflect.ValueOf(x) v := reflect.ValueOf(x)
fmt.Println("value:", v) fmt.Println("value:", v)
fmt.Println("type:", v.Type()) fmt.Println("type:", v.Type())
fmt.Println("kind:", v.Kind()) fmt.Println("kind:", v.Kind())
fmt.Println("value:", v.Float()) fmt.Println("value:", v.Float())
fmt.Println(v.Interface()) fmt.Println(v.Interface())
fmt.Printf("value is %5.2e\n", v.Interface()) fmt.Printf("value is %5.2e\n", v.Interface())
y := v.Interface().(float64) y := v.Interface().(float64)
fmt.Println(y) fmt.Println(y)
} }
/* output:
type: float64 /* output:
value: <float64 Value> type: float64
type: float64 value: <float64 Value>
kind: float64 type: float64
value: 3.4 kind: float64
3.4 value: 3.4
value is 3.40e+00 3.4
3.4 value is 3.40e+00
*/ 3.4
*/

View File

@@ -1,33 +1,34 @@
// reflect2.go // reflect2.go
package main package main
import ( import (
"fmt" "fmt"
"reflect" "reflect"
) )
func main() { func main() {
var x float64 = 3.4 var x float64 = 3.4
v := reflect.ValueOf(x) v := reflect.ValueOf(x)
// setting a value: // setting a value:
// v.SetFloat(3.1415) // Error: will panic: reflect.Value.SetFloat using unaddressable value // v.SetFloat(3.1415) // Error: will panic: reflect.Value.SetFloat using unaddressable value
fmt.Println("settability of v:", v.CanSet()) fmt.Println("settability of v:", v.CanSet())
v = reflect.ValueOf(&x) // Note: take the address of x. v = reflect.ValueOf(&x) // Note: take the address of x.
fmt.Println("type of v:", v.Type()) fmt.Println("type of v:", v.Type())
fmt.Println("settability of v:", v.CanSet()) fmt.Println("settability of v:", v.CanSet())
v = v.Elem() v = v.Elem()
fmt.Println("The Elem of v is: ", v) fmt.Println("The Elem of v is: ", v)
fmt.Println("settability of v:", v.CanSet()) fmt.Println("settability of v:", v.CanSet())
v.SetFloat(3.1415) // this works! v.SetFloat(3.1415) // this works!
fmt.Println(v.Interface()) fmt.Println(v.Interface())
fmt.Println(v) fmt.Println(v)
} }
/* Output:
settability of v: false /* Output:
type of v: *float64 settability of v: false
settability of v: false type of v: *float64
The Elem of v is: <float64 Value> settability of v: false
settability of v: true The Elem of v is: <float64 Value>
3.1415 settability of v: true
<float64 Value> 3.1415
*/ <float64 Value>
*/

View File

@@ -1,47 +1,48 @@
// reflect.go // reflect.go
package main package main
import ( import (
"fmt" "fmt"
"reflect" "reflect"
) )
type NotknownType struct { type NotknownType struct {
s1, s2, s3 string s1, s2, s3 string
} }
func (n NotknownType) String() string { func (n NotknownType) String() string {
return n.s1 + " - " + n.s2 + " - " + n.s3 return n.s1 + " - " + n.s2 + " - " + n.s3
} }
// variable to investigate: // variable to investigate:
var secret interface {} = NotknownType{"Ada", "Go", "Oberon"} var secret interface{} = NotknownType{"Ada", "Go", "Oberon"}
func main() { func main() {
value := reflect.ValueOf(secret) // <main.NotknownType Value> value := reflect.ValueOf(secret) // <main.NotknownType Value>
typ := reflect.TypeOf(secret) // main.NotknownType typ := reflect.TypeOf(secret) // main.NotknownType
// alternative: // alternative:
//typ := value.Type() // main.NotknownType //typ := value.Type() // main.NotknownType
fmt.Println(typ) fmt.Println(typ)
knd := value.Kind() // struct knd := value.Kind() // struct
fmt.Println(knd) fmt.Println(knd)
// iterate through the fields of the struct: // iterate through the fields of the struct:
for i:= 0; i < value.NumField(); i++ { for i := 0; i < value.NumField(); i++ {
fmt.Printf("Field %d: %v\n", i, value.Field(i)) fmt.Printf("Field %d: %v\n", i, value.Field(i))
// error: panic: reflect.Value.SetString using value obtained using unexported field // error: panic: reflect.Value.SetString using value obtained using unexported field
//value.Field(i).SetString("C#") //value.Field(i).SetString("C#")
} }
// call the first method, which is String(): // call the first method, which is String():
results := value.Method(0).Call(nil) results := value.Method(0).Call(nil)
fmt.Println(results) // [Ada - Go - Oberon] fmt.Println(results) // [Ada - Go - Oberon]
} }
/* Output:
main.NotknownType /* Output:
struct main.NotknownType
Field 0: Ada struct
Field 1: Go Field 0: Ada
Field 2: Oberon Field 1: Go
[Ada - Go - Oberon] Field 2: Oberon
*/ [Ada - Go - Oberon]
*/

View File

@@ -1,31 +1,32 @@
// reflect_struct2.go // reflect_struct2.go
package main package main
import ( import (
"fmt" "fmt"
"reflect" "reflect"
) )
type T struct { type T struct {
A int A int
B string B string
} }
func main() { func main() {
t := T{23, "skidoo"} t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem() s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type() typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ { for i := 0; i < s.NumField(); i++ {
f := s.Field(i) f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i, fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface()) typeOfT.Field(i).Name, f.Type(), f.Interface())
} }
s.Field(0).SetInt(77) s.Field(0).SetInt(77)
s.Field(1).SetString("Sunset Strip") s.Field(1).SetString("Sunset Strip")
fmt.Println("t is now", t) fmt.Println("t is now", t)
} }
/* Output:
0: A int = 23 /* Output:
1: B string = skidoo 0: A int = 23
t is now {77 Sunset Strip} 1: B string = skidoo
*/ t is now {77 Sunset Strip}
*/

View File

@@ -1,58 +1,60 @@
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Sorting using a general interface // Sorting using a general interface
package sort package sort
// Sorting interface // Sorting interface
type Interface interface { type Interface interface {
Len() int Len() int
Less(i, j int) bool Less(i, j int) bool
Swap(i, j int) Swap(i, j int)
} }
// General sort function // General sort function
func Sort(data Interface) { func Sort(data Interface) {
for i := 1; i < data.Len(); i++ { for i := 1; i < data.Len(); i++ {
for j := i; j > 0 && data.Less(j, j-1); j-- { for j := i; j > 0 && data.Less(j, j-1); j-- {
data.Swap(j, j-1) data.Swap(j, j-1)
} }
} }
} }
// Test if data is sorted // Test if data is sorted
func IsSorted(data Interface) bool { func IsSorted(data Interface) bool {
n := data.Len() n := data.Len()
for i := n - 1; i > 0; i-- { for i := n - 1; i > 0; i-- {
if data.Less(i, i-1) { if data.Less(i, i-1) {
return false return false
} }
} }
return true return true
} }
// Convenience types for common cases: IntArray // Convenience types for common cases: IntArray
type IntArray []int type IntArray []int
func (p IntArray) Len() int { return len(p) } func (p IntArray) Len() int { return len(p) }
func (p IntArray) Less(i, j int) bool { return p[i] < p[j] } func (p IntArray) Less(i, j int) bool { return p[i] < p[j] }
func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Float64Array []float64 type Float64Array []float64
func (p Float64Array) Len() int { return len(p) }
func (p Float64Array) Less(i, j int) bool { return p[i] < p[j] } func (p Float64Array) Len() int { return len(p) }
func (p Float64Array) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p Float64Array) Less(i, j int) bool { return p[i] < p[j] }
func (p Float64Array) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type StringArray []string
func (p StringArray) Len() int { return len(p) } type StringArray []string
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] }
func (p StringArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p StringArray) Len() int { return len(p) }
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] }
// Convenience wrappers for common cases func (p StringArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func SortInts(a []int) { Sort(IntArray(a)) }
func SortFloat64s(a []float64) { Sort(Float64Array(a)) } // Convenience wrappers for common cases
func SortStrings(a []string) { Sort(StringArray(a)) } func SortInts(a []int) { Sort(IntArray(a)) }
func SortFloat64s(a []float64) { Sort(Float64Array(a)) }
func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) } func SortStrings(a []string) { Sort(StringArray(a)) }
func Float64sAreSorted(a []float64) bool { return IsSorted(Float64Array(a)) }
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) } func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) }
func Float64sAreSorted(a []float64) bool { return IsSorted(Float64Array(a)) }
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) }

View File

@@ -1,82 +1,81 @@
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This package gives an example of how to use a custom package with interfaces // This package gives an example of how to use a custom package with interfaces
package main package main
import ( import (
"fmt" "./sort"
"./sort" "fmt"
) )
// sorting of slice of integers // sorting of slice of integers
func ints() { func ints() {
data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586} data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
a := sort.IntArray(data) //conversion to type IntArray a := sort.IntArray(data) //conversion to type IntArray
sort.Sort(a) sort.Sort(a)
if !sort.IsSorted(a) { if !sort.IsSorted(a) {
panic("fail") panic("fail")
} }
fmt.Printf("The sorted array is: %v\n", a) fmt.Printf("The sorted array is: %v\n", a)
} }
// sorting of slice of strings // sorting of slice of strings
func strings() { func strings() {
data := []string{"monday", "friday", "tuesday", "wednesday", "sunday","thursday", "", "saturday"} data := []string{"monday", "friday", "tuesday", "wednesday", "sunday", "thursday", "", "saturday"}
a := sort.StringArray(data) a := sort.StringArray(data)
sort.Sort(a) sort.Sort(a)
if !sort.IsSorted(a) { if !sort.IsSorted(a) {
panic("fail") panic("fail")
} }
fmt.Printf("The sorted array is: %v\n", a) fmt.Printf("The sorted array is: %v\n", a)
} }
// a type which describes a day of the week // a type which describes a day of the week
type day struct { type day struct {
num int num int
shortName string shortName string
longName string longName string
} }
type dayArray struct { type dayArray struct {
data []*day data []*day
} }
func (p *dayArray) Len() int { return len(p.data) } func (p *dayArray) Len() int { return len(p.data) }
func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num } func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num }
func (p *dayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i] } func (p *dayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i] }
// sorting of custom type day // sorting of custom type day
func days() { func days() {
Sunday := day{0, "SUN", "Sunday"} Sunday := day{0, "SUN", "Sunday"}
Monday := day{1, "MON", "Monday"} Monday := day{1, "MON", "Monday"}
Tuesday := day{2, "TUE", "Tuesday"} Tuesday := day{2, "TUE", "Tuesday"}
Wednesday := day{3, "WED", "Wednesday"} Wednesday := day{3, "WED", "Wednesday"}
Thursday := day{4, "THU", "Thursday"} Thursday := day{4, "THU", "Thursday"}
Friday := day{5, "FRI", "Friday"} Friday := day{5, "FRI", "Friday"}
Saturday := day{6, "SAT", "Saturday"} Saturday := day{6, "SAT", "Saturday"}
data := []*day{&Tuesday, &Thursday, &Wednesday, &Sunday, &Monday, &Friday, &Saturday} data := []*day{&Tuesday, &Thursday, &Wednesday, &Sunday, &Monday, &Friday, &Saturday}
a := dayArray{data} a := dayArray{data}
sort.Sort(&a) sort.Sort(&a)
if !sort.IsSorted(&a) { if !sort.IsSorted(&a) {
panic("fail") panic("fail")
} }
for _, d := range data { for _, d := range data {
fmt.Printf("%s ", d.longName) fmt.Printf("%s ", d.longName)
} }
fmt.Printf("\n") fmt.Printf("\n")
} }
func main() {
func main() { ints()
ints() strings()
strings() days()
days() }
}
/* Output:
/* Output: The sorted array is: [-5467984 -784 0 0 42 59 74 238 905 959 7586 7586 9845]
The sorted array is: [-5467984 -784 0 0 42 59 74 238 905 959 7586 7586 9845] The sorted array is: [ friday monday saturday sunday thursday tuesday wednesday]
The sorted array is: [ friday monday saturday sunday thursday tuesday wednesday] Sunday Monday Tuesday Wednesday Thursday Friday Saturday
Sunday Monday Tuesday Wednesday Thursday Friday Saturday */
*/

View File

@@ -1,23 +1,23 @@
// static.go // static.go
package main package main
import ( import (
"io" "bufio"
"os" "bytes"
"bufio" "fmt"
"bytes" "io"
"fmt" "os"
) )
var r io.Reader var r io.Reader
func main() { func main() {
r = os.Stdin r = os.Stdin
r = bufio.NewReader(r) r = bufio.NewReader(r)
r = new(bytes.Buffer) r = new(bytes.Buffer)
f, _ := os.Open("test.txt") f, _ := os.Open("test.txt")
r = bufio.NewReader(f) r = bufio.NewReader(f)
var s *bytes.Buffer = new(bytes.Buffer) var s *bytes.Buffer = new(bytes.Buffer)
r = s r = s
fmt.Println(s) fmt.Println(s)
} }

View File

@@ -43,8 +43,8 @@ package cgl
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"fmt"
"encoding/hex" "encoding/hex"
"fmt"
"io" "io"
"log" "log"
"reflect" "reflect"
@@ -120,7 +120,7 @@ func (uuid UUID) String() string {
// MORE ID FUNCTIONS // MORE ID FUNCTIONS
//-------------------- //--------------------
// LimitedSepIdentifier builds an identifier out of multiple parts, // LimitedSepIdentifier builds an identifier out of multiple parts,
// all as lowercase strings and concatenated with the separator // all as lowercase strings and concatenated with the separator
// Non letters and digits are exchanged with dashes and // Non letters and digits are exchanged with dashes and
// reduced to a maximum of one each. If limit is true only // reduced to a maximum of one each. If limit is true only
@@ -173,8 +173,8 @@ func Identifier(parts ...interface{}) string {
return SepIdentifier(":", parts...) return SepIdentifier(":", parts...)
} }
// TypeAsIdentifierPart transforms the name of the arguments type into // TypeAsIdentifierPart transforms the name of the arguments type into
// a part for identifiers. It's splitted at each uppercase char, // a part for identifiers. It's splitted at each uppercase char,
// concatenated with dashes and transferred to lowercase. // concatenated with dashes and transferred to lowercase.
func TypeAsIdentifierPart(i interface{}) string { func TypeAsIdentifierPart(i interface{}) string {
var buf bytes.Buffer var buf bytes.Buffer

View File

@@ -151,7 +151,7 @@ func (sm *SystemMonitor) MeasuringPointsMap(f func(*MeasuringPoint) interface{})
return resp.([]interface{}) return resp.([]interface{})
} }
// MeasuringPointsDo performs the function f for // MeasuringPointsDo performs the function f for
// all measuring points. // all measuring points.
func (sm *SystemMonitor) MeasuringPointsDo(f func(*MeasuringPoint)) { func (sm *SystemMonitor) MeasuringPointsDo(f func(*MeasuringPoint)) {
cmd := &command{cmdMeasuringPointsDo, f, nil} cmd := &command{cmdMeasuringPointsDo, f, nil}
@@ -450,7 +450,7 @@ type Measuring struct {
endTime int64 endTime int64
} }
// EndMEasuring ends a measuring and passes it to the // EndMEasuring ends a measuring and passes it to the
// measuring server in the background. // measuring server in the background.
func (m *Measuring) EndMeasuring() int64 { func (m *Measuring) EndMeasuring() int64 {
m.endTime = time.Nanoseconds() m.endTime = time.Nanoseconds()

View File

@@ -1,62 +1,62 @@
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
) )
type Square struct { type Square struct {
side float32 side float32
} }
type Circle struct { type Circle struct {
radius float32 radius float32
} }
type Shaper interface { type Shaper interface {
Area() float32 Area() float32
} }
func main() { func main() {
var areaIntf Shaper var areaIntf Shaper
sq1 := new(Square) sq1 := new(Square)
sq1.side = 5 sq1.side = 5
areaIntf = sq1 areaIntf = sq1
// Is Square the type of areaIntf ? // Is Square the type of areaIntf ?
if t, ok := areaIntf.(*Square); ok { if t, ok := areaIntf.(*Square); ok {
fmt.Printf("The type of areaIntf is: %T\n", t) fmt.Printf("The type of areaIntf is: %T\n", t)
} }
if u, ok := areaIntf.(*Circle); ok { if u, ok := areaIntf.(*Circle); ok {
fmt.Printf("The type of areaIntf is: %T\n", u) fmt.Printf("The type of areaIntf is: %T\n", u)
} else { } else {
fmt.Println("areaIntf does not contain a variable of type Circle") fmt.Println("areaIntf does not contain a variable of type Circle")
} }
// testing with switch: // testing with switch:
switch t := areaIntf.(type) { switch t := areaIntf.(type) {
case *Square: case *Square:
fmt.Printf("Type Square %T with value %v\n", t, t) fmt.Printf("Type Square %T with value %v\n", t, t)
case *Circle: case *Circle:
fmt.Printf("Type Circle %T with value %v\n", t, t) fmt.Printf("Type Circle %T with value %v\n", t, t)
/* /*
case bool: case bool:
fmt.Printf("Type boolean %t\n", t) fmt.Printf("Type boolean %t\n", t)
case int: case int:
fmt.Printf("Type int %d\n", t) fmt.Printf("Type int %d\n", t)
case *bool: case *bool:
fmt.Printf("Type pointer to boolean %t\n", *t) fmt.Printf("Type pointer to boolean %t\n", *t)
case *int: case *int:
fmt.Printf("Type pointer to int %d\n", *t) fmt.Printf("Type pointer to int %d\n", *t)
*/ */
default: default:
fmt.Printf("Unexpected type %T", t) fmt.Printf("Unexpected type %T", t)
} }
} }
func (sq *Square) Area() float32 { func (sq *Square) Area() float32 {
return sq.side * sq.side return sq.side * sq.side
} }
func (ci *Circle) Area() float32 { func (ci *Circle) Area() float32 {
return ci.radius * ci.radius * math.Pi return ci.radius * ci.radius * math.Pi
} }

View File

@@ -1,36 +1,35 @@
package main package main
import ( import (
"os" "bufio"
"io" "flag"
"fmt" "fmt"
"bufio" "io"
"flag" "os"
) )
func cat(r *bufio.Reader) { func cat(r *bufio.Reader) {
for { for {
buf, err := r.ReadBytes('\n') buf, err := r.ReadBytes('\n')
if err == io.EOF { if err == io.EOF {
break break
} }
fmt.Fprintf(os.Stdout, "%s", buf) fmt.Fprintf(os.Stdout, "%s", buf)
} }
return return
} }
func main() { func main() {
flag.Parse() flag.Parse()
if flag.NArg() == 0 { if flag.NArg() == 0 {
cat(bufio.NewReader(os.Stdin)) cat(bufio.NewReader(os.Stdin))
} }
for i := 0; i < flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
f, err := os.Open(flag.Arg(i)) f, err := os.Open(flag.Arg(i))
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "%s:error reading from %s: %s\n", os.Args[0], flag.Arg(i), err.Error()) fmt.Fprintf(os.Stderr, "%s:error reading from %s: %s\n", os.Args[0], flag.Arg(i), err.Error())
continue continue
} }
cat(bufio.NewReader(f)) cat(bufio.NewReader(f))
} }
} }

View File

@@ -1,41 +1,41 @@
package main package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"os" "os"
) )
func cat(f *os.File) { func cat(f *os.File) {
const NBUF = 512 const NBUF = 512
var buf [NBUF]byte var buf [NBUF]byte
for { for {
switch nr, err := f.Read(buf[:]); true { switch nr, err := f.Read(buf[:]); true {
case nr < 0: case nr < 0:
fmt.Fprintf(os.Stderr, "cat: error reading: %s\n", err.Error()) fmt.Fprintf(os.Stderr, "cat: error reading: %s\n", err.Error())
os.Exit(1) os.Exit(1)
case nr == 0: // EOF case nr == 0: // EOF
return return
case nr > 0: case nr > 0:
if nw, ew := os.Stdout.Write(buf[0:nr]); nw != nr { if nw, ew := os.Stdout.Write(buf[0:nr]); nw != nr {
fmt.Fprintf(os.Stderr, "cat: error writing: %s\n", ew.Error()) fmt.Fprintf(os.Stderr, "cat: error writing: %s\n", ew.Error())
} }
} }
} }
} }
func main() { func main() {
flag.Parse() // Scans the arg list and sets up flags flag.Parse() // Scans the arg list and sets up flags
if flag.NArg() == 0 { if flag.NArg() == 0 {
cat(os.Stdin) cat(os.Stdin)
} }
for i := 0; i < flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
f, err := os.Open(flag.Arg(i)) f, err := os.Open(flag.Arg(i))
if f == nil { if f == nil {
fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err) fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err)
os.Exit(1) os.Exit(1)
} }
cat(f) cat(f)
f.Close() f.Close()
} }
} }

View File

@@ -1,29 +1,29 @@
package main package main
import ( import (
"os" "flag" // command line option parser
"flag" // command line option parser "os"
) )
var NewLine = flag.Bool("n", false, "print newline") // echo -n flag, of type *bool var NewLine = flag.Bool("n", false, "print newline") // echo -n flag, of type *bool
const ( const (
Space = " " Space = " "
Newline = "\n" Newline = "\n"
) )
func main() { func main() {
flag.PrintDefaults() flag.PrintDefaults()
flag.Parse() // Scans the arg list and sets up flags flag.Parse() // Scans the arg list and sets up flags
var s string = "" var s string = ""
for i := 0; i < flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
if i > 0 { if i > 0 {
s += " " s += " "
if *NewLine { // -n is parsed, flag becomes true if *NewLine { // -n is parsed, flag becomes true
s += Newline s += Newline
} }
} }
s += flag.Arg(i) s += flag.Arg(i)
} }
os.Stdout.WriteString(s) os.Stdout.WriteString(s)
} }

View File

@@ -1,29 +1,29 @@
// filecopy.go // filecopy.go
package main package main
import ( import (
"fmt" "fmt"
"io" "io"
"os" "os"
) )
func main() { func main() {
CopyFile("target.txt", "source.txt") CopyFile("target.txt", "source.txt")
fmt.Println("Copy done!") fmt.Println("Copy done!")
} }
func CopyFile(dstName, srcName string) (written int64, err error) { func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName) src, err := os.Open(srcName)
if err != nil { if err != nil {
return return
} }
defer src.Close() defer src.Close()
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644) dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil { if err != nil {
return return
} }
defer dst.Close() defer dst.Close()
return io.Copy(dst, src) return io.Copy(dst, src)
} }

View File

@@ -1,34 +1,34 @@
package main package main
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"io" "io"
"os" "os"
) )
func main() { func main() {
// var inputFile *os.File // var inputFile *os.File
// var inputError, readerError os.Error // var inputError, readerError os.Error
// var inputReader *bufio.Reader // var inputReader *bufio.Reader
// var inputString string // var inputString string
inputFile, inputError := os.Open("input.dat") inputFile, inputError := os.Open("input.dat")
if inputError != nil { if inputError != nil {
fmt.Printf("An error occurred on opening the inputfile\n" + fmt.Printf("An error occurred on opening the inputfile\n" +
"Does the file exist?\n" + "Does the file exist?\n" +
"Have you got acces to it?\n") "Have you got acces to it?\n")
return // exit the function on error return // exit the function on error
} }
defer inputFile.Close() defer inputFile.Close()
inputReader := bufio.NewReader(inputFile) inputReader := bufio.NewReader(inputFile)
for { for {
inputString, readerError := inputReader.ReadString('\n') inputString, readerError := inputReader.ReadString('\n')
if readerError == io.EOF { if readerError == io.EOF {
return // error or EOF return // error or EOF
} }
fmt.Printf("The input was: %s", inputString) fmt.Printf("The input was: %s", inputString)
} }
} }

View File

@@ -1,28 +1,28 @@
package main package main
import ( import (
"os" "bufio"
"bufio" "fmt"
"fmt" "os"
) )
func main () { func main() {
// var outputWriter *bufio.Writer // var outputWriter *bufio.Writer
// var outputFile *os.File // var outputFile *os.File
// var outputError os.Error // var outputError os.Error
// var outputString string // var outputString string
outputFile, outputError := os.OpenFile("output.dat", os.O_WRONLY|os.O_CREATE, 0666) outputFile, outputError := os.OpenFile("output.dat", os.O_WRONLY|os.O_CREATE, 0666)
if outputError != nil { if outputError != nil {
fmt.Printf("An error occurred with file opening or creation\n") fmt.Printf("An error occurred with file opening or creation\n")
return return
} }
defer outputFile.Close() defer outputFile.Close()
outputWriter := bufio.NewWriter(outputFile) outputWriter := bufio.NewWriter(outputFile)
outputString := "hello world!\n" outputString := "hello world!\n"
for i:=0; i<10; i++ { for i := 0; i < 10; i++ {
outputWriter.WriteString(outputString) outputWriter.WriteString(outputString)
} }
outputWriter.Flush() outputWriter.Flush()
} }

View File

@@ -1,10 +1,10 @@
package main package main
import "os" import "os"
func main() { func main() {
os.Stdout.WriteString("hello, world\n") os.Stdout.WriteString("hello, world\n")
f, _ := os.OpenFile("test", os.O_CREATE|os.O_WRONLY, 0) f, _ := os.OpenFile("test", os.O_CREATE|os.O_WRONLY, 0)
defer f.Close() defer f.Close()
f.WriteString("hello, world in a file\n") f.WriteString("hello, world in a file\n")
} }

View File

@@ -1,41 +1,42 @@
// gob1.go // gob1.go
package main package main
import ( import (
"bytes" "bytes"
"fmt" "encoding/gob"
"encoding/gob" "fmt"
"log" "log"
) )
type P struct { type P struct {
X, Y, Z int X, Y, Z int
Name string Name string
} }
type Q struct { type Q struct {
X, Y *int32 X, Y *int32
Name string Name string
} }
func main() { func main() {
// Initialize the encoder and decoder. Normally enc and dec would be // Initialize the encoder and decoder. Normally enc and dec would be
// bound to network connections and the encoder and decoder would // bound to network connections and the encoder and decoder would
// run in different processes. // run in different processes.
var network bytes.Buffer // Stand-in for a network connection var network bytes.Buffer // Stand-in for a network connection
enc := gob.NewEncoder(&network) // Will write to network. enc := gob.NewEncoder(&network) // Will write to network.
dec := gob.NewDecoder(&network) // Will read from network. dec := gob.NewDecoder(&network) // Will read from network.
// Encode (send) the value. // Encode (send) the value.
err := enc.Encode(P{3, 4, 5, "Pythagoras"}) err := enc.Encode(P{3, 4, 5, "Pythagoras"})
if err != nil { if err != nil {
log.Fatal("encode error:", err) log.Fatal("encode error:", err)
} }
// Decode (receive) the value. // Decode (receive) the value.
var q Q var q Q
err = dec.Decode(&q) err = dec.Decode(&q)
if err != nil { if err != nil {
log.Fatal("decode error:", err) log.Fatal("decode error:", err)
} }
fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y) fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y)
} }
// Output: "Pythagoras": {3,4}
// Output: "Pythagoras": {3,4}

View File

@@ -1,39 +1,38 @@
// gob2.go // gob2.go
package main package main
import ( import (
"encoding/gob" "encoding/gob"
"log" "log"
"os" "os"
) )
type Address struct { type Address struct {
Type string Type string
City string City string
Country string Country string
} }
type VCard struct { type VCard struct {
FirstName string FirstName string
LastName string LastName string
Addresses []*Address Addresses []*Address
Remark string Remark string
} }
var content string var content string
func main() { func main() {
pa := &Address{"private", "Aartselaar","Belgium"} pa := &Address{"private", "Aartselaar", "Belgium"}
wa := &Address{"work", "Boom", "Belgium"} wa := &Address{"work", "Boom", "Belgium"}
vc := VCard{"Jan", "Kersschot", []*Address{pa,wa}, "none"} vc := VCard{"Jan", "Kersschot", []*Address{pa, wa}, "none"}
// fmt.Printf("%v: \n", vc) // {Jan Kersschot [0x126d2b80 0x126d2be0] none}: // fmt.Printf("%v: \n", vc) // {Jan Kersschot [0x126d2b80 0x126d2be0] none}:
// using an encoder: // using an encoder:
file, _ := os.OpenFile("vcard.gob", os.O_CREATE|os.O_WRONLY, 0666) file, _ := os.OpenFile("vcard.gob", os.O_CREATE|os.O_WRONLY, 0666)
defer file.Close() defer file.Close()
enc := gob.NewEncoder(file) enc := gob.NewEncoder(file)
err := enc.Encode(vc) err := enc.Encode(vc)
if err != nil { if err != nil {
log.Println("Error in encoding gob") log.Println("Error in encoding gob")
} }
} }

View File

@@ -1,35 +1,35 @@
// gzipped.go // gzipped.go
package main package main
import ( import (
"fmt" "bufio"
"bufio" "compress/gzip"
"os" "fmt"
"compress/gzip" "os"
) )
func main() { func main() {
fName := "MyFile.gz" fName := "MyFile.gz"
var r *bufio.Reader var r *bufio.Reader
fi, err := os.Open(fName) fi, err := os.Open(fName)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "%v, Can't open %s: error: %s\n", os.Args[0], fName, fmt.Fprintf(os.Stderr, "%v, Can't open %s: error: %s\n", os.Args[0], fName,
err) err)
os.Exit(1) os.Exit(1)
} }
fz, err := gzip.NewReader(fi) fz, err := gzip.NewReader(fi)
if err != nil { if err != nil {
r = bufio.NewReader(fi) r = bufio.NewReader(fi)
} else { } else {
r = bufio.NewReader(fz) r = bufio.NewReader(fz)
} }
for { for {
line, err := r.ReadString('\n') line, err := r.ReadString('\n')
if err != nil { if err != nil {
fmt.Println("Done reading file") fmt.Println("Done reading file")
os.Exit(0) os.Exit(0)
} }
fmt.Println(line) fmt.Println(line)
} }
} }

View File

@@ -1,31 +1,32 @@
// hash_sha1.go // hash_sha1.go
package main package main
import ( import (
"fmt" "crypto/sha1"
"crypto/sha1" "fmt"
"io" "io"
"log" "log"
) )
func main() { func main() {
hasher := sha1.New() hasher := sha1.New()
io.WriteString(hasher, "test") io.WriteString(hasher, "test")
b := []byte{} b := []byte{}
fmt.Printf("Result: %x\n", hasher.Sum(b)) fmt.Printf("Result: %x\n", hasher.Sum(b))
fmt.Printf("Result: %d\n", hasher.Sum(b)) fmt.Printf("Result: %d\n", hasher.Sum(b))
// //
hasher.Reset() hasher.Reset()
data := []byte("We shall overcome!") data := []byte("We shall overcome!")
n, err := hasher.Write(data) n, err := hasher.Write(data)
if n!=len(data) || err!=nil { if n != len(data) || err != nil {
log.Printf("Hash write error: %v / %v", n, err) log.Printf("Hash write error: %v / %v", n, err)
} }
checksum := hasher.Sum(b) checksum := hasher.Sum(b)
fmt.Printf("Result: %x\n", checksum) fmt.Printf("Result: %x\n", checksum)
} }
/* Output:
Result: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 /* Output:
Result: [169 74 143 229 204 177 155 166 28 76 8 115 211 145 233 135 152 47 187 211] Result: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
Result: e2222bfc59850bbb00a722e764a555603bb59b2a Result: [169 74 143 229 204 177 155 166 28 76 8 115 211 145 233 135 152 47 187 211]
*/ Result: e2222bfc59850bbb00a722e764a555603bb59b2a
*/

View File

@@ -1,18 +1,18 @@
// interfaces being used in the GO-package fmt // interfaces being used in the GO-package fmt
package main package main
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"os" "os"
) )
func main() { func main() {
// unbuffered // unbuffered
fmt.Fprintf(os.Stdout, "%s\n", "hello world! - unbuffered") fmt.Fprintf(os.Stdout, "%s\n", "hello world! - unbuffered")
// buffered: os.Stdout implements io.Writer // buffered: os.Stdout implements io.Writer
buf := bufio.NewWriter(os.Stdout) buf := bufio.NewWriter(os.Stdout)
// and now so does buf. // and now so does buf.
fmt.Fprintf(buf, "%s\n", "hello world! - buffered") fmt.Fprintf(buf, "%s\n", "hello world! - buffered")
buf.Flush() buf.Flush()
} }

View File

@@ -1,40 +1,40 @@
// json.go // json.go
package main package main
import ( import (
"fmt" "encoding/json"
"encoding/json" "fmt"
"log" "log"
"os" "os"
) )
type Address struct { type Address struct {
Type string Type string
City string City string
Country string Country string
} }
type VCard struct { type VCard struct {
FirstName string FirstName string
LastName string LastName string
Addresses []*Address Addresses []*Address
Remark string Remark string
} }
func main() { func main() {
pa := &Address{"private", "Aartselaar","Belgium"} pa := &Address{"private", "Aartselaar", "Belgium"}
wa := &Address{"work", "Boom", "Belgium"} wa := &Address{"work", "Boom", "Belgium"}
vc := VCard{"Jan", "Kersschot", []*Address{pa,wa}, "none"} vc := VCard{"Jan", "Kersschot", []*Address{pa, wa}, "none"}
// fmt.Printf("%v: \n", vc) // {Jan Kersschot [0x126d2b80 0x126d2be0] none}: // fmt.Printf("%v: \n", vc) // {Jan Kersschot [0x126d2b80 0x126d2be0] none}:
// JSON format: // JSON format:
js, _ := json.Marshal(vc) js, _ := json.Marshal(vc)
fmt.Printf("JSON format: %s", js) fmt.Printf("JSON format: %s", js)
// using an encoder: // using an encoder:
file, _ := os.OpenFile("vcard.json", os.O_CREATE|os.O_WRONLY, 0) file, _ := os.OpenFile("vcard.json", os.O_CREATE|os.O_WRONLY, 0)
defer file.Close() defer file.Close()
enc := json.NewEncoder(file) enc := json.NewEncoder(file)
err := enc.Encode(vc) err := enc.Encode(vc)
if err != nil { if err != nil {
log.Println("Error in encoding json") log.Println("Error in encoding json")
} }
} }

View File

@@ -1,54 +1,55 @@
// json_xml_case.go // json_xml_case.go
package main package main
import ( import (
"encoding/json" "encoding/json"
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"log" "log"
"strings" "strings"
) )
type thing struct { type thing struct {
Field1 int Field1 int
Field2 string Field2 string
} }
func main() { func main() {
x := `<x><field1>423</field1><field2>hello from xml</field2></x>` x := `<x><field1>423</field1><field2>hello from xml</field2></x>`
j := `{"field1": 423, "field2": "hello from json"}` j := `{"field1": 423, "field2": "hello from json"}`
tx := thing{} tx := thing{}
if err := xml.Unmarshal(strings.NewReader(x), &tx); err != nil { if err := xml.Unmarshal(strings.NewReader(x), &tx); err != nil {
log.Fatalf("Error unmarshaling XML: %v", err) log.Fatalf("Error unmarshaling XML: %v", err)
} }
tj := thing{} tj := thing{}
if err := json.Unmarshal([]byte(j), &tj); err != nil { if err := json.Unmarshal([]byte(j), &tj); err != nil {
log.Fatalf("Error unmarshaling JSON: %v", err) log.Fatalf("Error unmarshaling JSON: %v", err)
} }
fmt.Printf("From JSON: %#v\n", tj) fmt.Printf("From JSON: %#v\n", tj)
fmt.Printf("From XML: %#v\n", tx) fmt.Printf("From XML: %#v\n", tx)
} }
/* Output with
type thing struct { /* Output with
Field1 int type thing struct {
Field2 string Field1 int
}: Field2 string
}:
From XML: main.thing{Field1:0, Field2:""} // All matching is case sensitive!
From JSON: main.thing{Field1:423, Field2:"hello from json"} From XML: main.thing{Field1:0, Field2:""} // All matching is case sensitive!
From JSON: main.thing{Field1:423, Field2:"hello from json"}
Output with
type thing struct { Output with
field1 int type thing struct {
field2 string field1 int
}: field2 string
}:
2012/02/22 10:51:11 Error unmarshaling JSON: json: cannot unmarshal object
field1" into unexported field field1 of type main.thing 2012/02/22 10:51:11 Error unmarshaling JSON: json: cannot unmarshal object
field1" into unexported field field1 of type main.thing
JSON uses reflection to unmarshal!
*/ JSON uses reflection to unmarshal!
*/

View File

@@ -1,16 +1,16 @@
// os_args.go // os_args.go
package main package main
import ( import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
) )
func main() { func main() {
who := "Alice " who := "Alice "
if len(os.Args) > 1 { if len(os.Args) > 1 {
who += strings.Join(os.Args[1:], " ") who += strings.Join(os.Args[1:], " ")
} }
fmt.Println("Good Morning", who) fmt.Println("Good Morning", who)
} }

View File

@@ -1,38 +1,39 @@
// read_csvfile.go // read_csvfile.go
package main package main
import ( import (
"fmt" "fmt"
"os" "os"
// "io/ioutil" // "io/ioutil"
// "strings" // "strings"
) )
func main() { func main() {
file, err := os.Open("products2.txt") file, err := os.Open("products2.txt")
if err != nil { if err != nil {
panic(err) panic(err)
} }
defer file.Close() defer file.Close()
var col1, col2, col3 []string var col1, col2, col3 []string
for { for {
var v1, v2, v3 string var v1, v2, v3 string
_, err := fmt.Fscanln(file, &v1, &v2, &v3) _, err := fmt.Fscanln(file, &v1, &v2, &v3)
if err != nil { if err != nil {
break break
} }
col1 = append(col1, v1) col1 = append(col1, v1)
col2 = append(col2, v2) col2 = append(col2, v2)
col3 = append(col3, v3) col3 = append(col3, v3)
} }
fmt.Println(col1) fmt.Println(col1)
fmt.Println(col2) fmt.Println(col2)
fmt.Println(col3) fmt.Println(col3)
} }
/* Output:
[ABC FUNC GO] /* Output:
[40 56 45] [ABC FUNC GO]
[150 280 356] [40 56 45]
*/ [150 280 356]
*/

View File

@@ -1,30 +1,28 @@
// read_files.go // read_files.go
package main package main
import ( import (
"bufio" "bufio"
"flag" "flag"
"fmt" "fmt"
"io" "io"
"os" "os"
) )
func main() { func main() {
fmt.Printf("Reading files...\n") fmt.Printf("Reading files...\n")
flag.Parse() flag.Parse()
for i := 0; i < flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
fmt.Printf("[File: %v]\n", flag.Arg(i)) fmt.Printf("[File: %v]\n", flag.Arg(i))
fin, err := os.Open(flag.Arg(i)) fin, err := os.Open(flag.Arg(i))
if err != nil { if err != nil {
fmt.Printf("The file %v does not exist!\n", flag.Arg(i)) fmt.Printf("The file %v does not exist!\n", flag.Arg(i))
break break
} }
r := bufio.NewReader(fin) r := bufio.NewReader(fin)
for line, _, err := r.ReadLine(); for line, _, err := r.ReadLine(); err != io.EOF; line, _, err = r.ReadLine() {
err != io.EOF; fmt.Printf("Lines: %v (error %v)\n", string(line), err)
line, _, err = r.ReadLine() { }
fmt.Printf("Lines: %v (error %v)\n", string(line), err) }
} }
}
}

View File

@@ -1,21 +1,21 @@
// read_write_file.go // read_write_file.go
package main package main
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
) )
func main() { func main() {
inputFile := "products.txt" inputFile := "products.txt"
outputFile := "products_copy.txt" outputFile := "products_copy.txt"
buf, err := ioutil.ReadFile(inputFile) buf, err := ioutil.ReadFile(inputFile)
if err != nil { if err != nil {
panic(err.Error()) panic(err.Error())
} }
fmt.Printf("%s\n", string(buf)) fmt.Printf("%s\n", string(buf))
err = ioutil.WriteFile(outputFile, buf, 0644) // oct, not hex err = ioutil.WriteFile(outputFile, buf, 0644) // oct, not hex
if err != nil { if err != nil {
panic(err.Error()) panic(err.Error())
} }
} }

View File

@@ -1,24 +1,24 @@
// read input from the console: // read input from the console:
package main package main
import ( import (
"fmt" "fmt"
) )
var ( var (
firstName, lastName, s string firstName, lastName, s string
i int i int
f float32 f float32
input = "56.12 / 5212 / Go" input = "56.12 / 5212 / Go"
format = "%f / %d / %s" format = "%f / %d / %s"
) )
func main() { func main() {
fmt.Println("Please enter your full name: ") fmt.Println("Please enter your full name: ")
fmt.Scanln(&firstName, &lastName) fmt.Scanln(&firstName, &lastName)
// fmt.Scanf("%s %s", &firstName, &lastName) // fmt.Scanf("%s %s", &firstName, &lastName)
fmt.Printf("Hi %s %s!\n", firstName, lastName) // Hi Chris Naegels fmt.Printf("Hi %s %s!\n", firstName, lastName) // Hi Chris Naegels
fmt.Sscanf(input, format, &f, &i, &s) fmt.Sscanf(input, format, &f, &i, &s)
fmt.Println("From the string we read: ", f, i, s) // From the string we read: 56.12 5212 Go fmt.Println("From the string we read: ", f, i, s) // From the string we read: 56.12 5212 Go
} }

View File

@@ -1,22 +1,22 @@
// read input from the console: // read input from the console:
package main package main
import ( import (
"fmt" "bufio"
"bufio" "fmt"
"os" "os"
) )
var inputReader *bufio.Reader var inputReader *bufio.Reader
var input string var input string
var err error var err error
func main() { func main() {
inputReader = bufio.NewReader(os.Stdin) // reader for input inputReader = bufio.NewReader(os.Stdin) // reader for input
fmt.Println("Please enter some input: ") fmt.Println("Please enter some input: ")
input, err = inputReader.ReadString('\n') input, err = inputReader.ReadString('\n')
if err == nil { if err == nil {
fmt.Printf("The input was: %s\n", input) fmt.Printf("The input was: %s\n", input)
} }
} }

View File

@@ -1,41 +1,51 @@
package main package main
import ( import (
"fmt" "bufio"
"os" "fmt"
"bufio" "os"
) )
func main() { func main() {
inputReader := bufio.NewReader(os.Stdin) inputReader := bufio.NewReader(os.Stdin)
fmt.Println("Please enter your name:") fmt.Println("Please enter your name:")
input, err := inputReader.ReadString('\n') input, err := inputReader.ReadString('\n')
if err != nil { if err != nil {
fmt.Println("There were errors reading, exiting program.") fmt.Println("There were errors reading, exiting program.")
return return
} }
fmt.Printf("Your name is %s", input) fmt.Printf("Your name is %s", input)
// For Unix: test with delimiter "\n", for Windows: test with "\r\n" // For Unix: test with delimiter "\n", for Windows: test with "\r\n"
switch input { switch input {
case "Philip\r\n": fmt.Println("Welcome Philip!") case "Philip\r\n":
case "Chris\r\n": fmt.Println("Welcome Chris!") fmt.Println("Welcome Philip!")
case "Ivo\r\n": fmt.Println("Welcome Ivo!") case "Chris\r\n":
default: fmt.Printf("You are not welcome here! Goodbye!") fmt.Println("Welcome Chris!")
} case "Ivo\r\n":
fmt.Println("Welcome Ivo!")
// version 2: default:
switch input { fmt.Printf("You are not welcome here! Goodbye!")
case "Philip\r\n": fallthrough }
case "Ivo\r\n": fallthrough
case "Chris\r\n": fmt.Printf("Welcome %s\n", input) // version 2:
default: fmt.Printf("You are not welcome here! Goodbye!\n") switch input {
} case "Philip\r\n":
fallthrough
// version 3: case "Ivo\r\n":
switch input { fallthrough
case "Philip\r\n", "Ivo\r\n": fmt.Printf("Welcome %s\n", input) case "Chris\r\n":
default: fmt.Printf("You are not welcome here! Goodbye!\n") fmt.Printf("Welcome %s\n", input)
} default:
} fmt.Printf("You are not welcome here! Goodbye!\n")
}
// version 3:
switch input {
case "Philip\r\n", "Ivo\r\n":
fmt.Printf("Welcome %s\n", input)
default:
fmt.Printf("You are not welcome here! Goodbye!\n")
}
}

View File

@@ -1,49 +1,50 @@
// xml.go // xml.go
package main package main
import ( import (
"fmt" "encoding/xml"
"strings" "fmt"
"encoding/xml" "strings"
) )
var t, token xml.Token var t, token xml.Token
var err error var err error
func main() { func main() {
input := "<Person><FirstName>Laura</FirstName><LastName>Lynn</LastName></Person>" input := "<Person><FirstName>Laura</FirstName><LastName>Lynn</LastName></Person>"
inputReader := strings.NewReader(input) inputReader := strings.NewReader(input)
p := xml.NewDecoder(inputReader) p := xml.NewDecoder(inputReader)
for t, err = p.Token(); err == nil; t, err = p.Token() { for t, err = p.Token(); err == nil; t, err = p.Token() {
switch token := t.(type) { switch token := t.(type) {
case xml.StartElement: case xml.StartElement:
name := token.Name.Local name := token.Name.Local
fmt.Printf("Token name: %s\n", name) fmt.Printf("Token name: %s\n", name)
for _, attr := range token.Attr { for _, attr := range token.Attr {
attrName := attr.Name.Local attrName := attr.Name.Local
attrValue := attr.Value attrValue := attr.Value
fmt.Printf("An attribute is: %s %s\n", attrName, attrValue) fmt.Printf("An attribute is: %s %s\n", attrName, attrValue)
// ... // ...
} }
case xml.EndElement: case xml.EndElement:
fmt.Println("End of token") fmt.Println("End of token")
case xml.CharData: case xml.CharData:
content := string([]byte(token)) content := string([]byte(token))
fmt.Printf("This is the content: %v\n", content ) fmt.Printf("This is the content: %v\n", content)
// ... // ...
default: default:
// ... // ...
} }
} }
} }
/* Output:
Token name: Person /* Output:
Token name: FirstName Token name: Person
This is the content: Laura Token name: FirstName
End of token This is the content: Laura
Token name: LastName End of token
This is the content: Lynn Token name: LastName
End of token This is the content: Lynn
End of token End of token
*/ End of token
*/

View File

@@ -1,14 +1,15 @@
// errors.go // errors.go
package main package main
import ( import (
"errors" "errors"
"fmt" "fmt"
) )
var errNotFound error = errors.New("Not found error") var errNotFound error = errors.New("Not found error")
func main() { func main() {
fmt.Printf("error: %v", errNotFound) fmt.Printf("error: %v", errNotFound)
} }
// error: Not found error
// error: Not found error

View File

@@ -1,10 +1,10 @@
// even.go // even.go
package even package even
func Even(i int) bool { // Exported function func Even(i int) bool { // Exported function
return i%2 == 0 return i%2 == 0
} }
func Odd(i int) bool { // Exported function func Odd(i int) bool { // Exported function
return i%2 != 0 return i%2 != 0
} }

View File

@@ -1,27 +1,27 @@
// oddeven_test.go // oddeven_test.go
package even package even
import "testing" import "testing"
func TestEven(t *testing.T) { func TestEven(t *testing.T) {
if !Even(10) { if !Even(10) {
t.Log(" 10 must be even!") t.Log(" 10 must be even!")
t.Fail() t.Fail()
} }
if Even(7) { if Even(7) {
t.Log(" 7 is not even!") t.Log(" 7 is not even!")
t.Fail() t.Fail()
} }
} }
func TestOdd(t *testing.T) { func TestOdd(t *testing.T) {
if !Odd(11) { if !Odd(11) {
t.Log(" 11 must be odd!") t.Log(" 11 must be odd!")
t.Fail() t.Fail()
} }
if Odd(10) { if Odd(10) {
t.Log(" 10 is not odd!") t.Log(" 10 is not odd!")
t.Fail() t.Fail()
} }
} }

View File

@@ -1,13 +1,13 @@
// test_oddeven.go // test_oddeven.go
package main package main
import ( import (
"fmt" "even/even"
"even/even" "fmt"
) )
func main() { func main() {
for i:=0; i<=100; i++ { for i := 0; i <= 100; i++ {
fmt.Printf("Is the integer %d even? %v\n", i, even.Even(i)) fmt.Printf("Is the integer %d even? %v\n", i, even.Even(i))
} }
} }

View File

@@ -1,61 +1,61 @@
// exec.go // exec.go
package main package main
import (
"fmt" import (
"os/exec" "fmt"
"os" "os"
) "os/exec"
)
func main() {
// 1) os.StartProcess // func main() {
/*********************/ // 1) os.StartProcess //
/* Linux: */ /*********************/
env := os.Environ() /* Linux: */
procAttr := &os.ProcAttr{ env := os.Environ()
Env: env, procAttr := &os.ProcAttr{
Files: []*os.File{ Env: env,
os.Stdin, Files: []*os.File{
os.Stdout, os.Stdin,
os.Stderr, os.Stdout,
}, os.Stderr,
} },
// 1st example: list files }
pid, err := os.StartProcess("/bin/ls", []string{"ls", "-l"}, procAttr) // 1st example: list files
if err != nil { pid, err := os.StartProcess("/bin/ls", []string{"ls", "-l"}, procAttr)
fmt.Printf("Error %v starting process!", err) // if err != nil {
os.Exit(1) fmt.Printf("Error %v starting process!", err) //
} os.Exit(1)
fmt.Printf("The process id is %v", pid) }
// 2nd example: show all processes fmt.Printf("The process id is %v", pid)
pid, err = os.StartProcess("/bin/ps", []string{"-e", "-opid,ppid,comm"}, procAttr) // 2nd example: show all processes
if err != nil { pid, err = os.StartProcess("/bin/ps", []string{"-e", "-opid,ppid,comm"}, procAttr)
fmt.Printf("Error %v starting process!", err) // if err != nil {
os.Exit(1) fmt.Printf("Error %v starting process!", err) //
} os.Exit(1)
fmt.Printf("The process id is %v", pid) }
/* Output 1st: fmt.Printf("The process id is %v", pid)
The process id is &{2054 0}total 2056 /* Output 1st:
-rwxr-xr-x 1 ivo ivo 1157555 2011-07-04 16:48 Mieken_exec The process id is &{2054 0}total 2056
-rw-r--r-- 1 ivo ivo 2124 2011-07-04 16:48 Mieken_exec.go -rwxr-xr-x 1 ivo ivo 1157555 2011-07-04 16:48 Mieken_exec
-rw-r--r-- 1 ivo ivo 18528 2011-07-04 16:48 Mieken_exec_go_.6 -rw-r--r-- 1 ivo ivo 2124 2011-07-04 16:48 Mieken_exec.go
-rwxr-xr-x 1 ivo ivo 913920 2011-06-03 16:13 panic.exe -rw-r--r-- 1 ivo ivo 18528 2011-07-04 16:48 Mieken_exec_go_.6
-rw-r--r-- 1 ivo ivo 180 2011-04-11 20:39 panic.go -rwxr-xr-x 1 ivo ivo 913920 2011-06-03 16:13 panic.exe
*/ -rw-r--r-- 1 ivo ivo 180 2011-04-11 20:39 panic.go
*/
// 2) exec.Run //
/***************/ // 2) exec.Run //
// Linux: OK, but not for ls ? /***************/
// cmd := exec.Command("ls", "-l") // no error, but doesn't show anything ? // Linux: OK, but not for ls ?
// cmd := exec.Command("ls") // no error, but doesn't show anything ? // cmd := exec.Command("ls", "-l") // no error, but doesn't show anything ?
cmd := exec.Command("gedit") // this opens a gedit-window // cmd := exec.Command("ls") // no error, but doesn't show anything ?
err = cmd.Run() cmd := exec.Command("gedit") // this opens a gedit-window
if err != nil { err = cmd.Run()
fmt.Printf("Error %v executing command!", err) if err != nil {
os.Exit(1) fmt.Printf("Error %v executing command!", err)
} os.Exit(1)
fmt.Printf("The command is %v", cmd) }
// The command is &{/bin/ls [ls -l] [] <nil> <nil> <nil> 0xf840000210 <nil> true [0xf84000ea50 0xf84000e9f0 0xf84000e9c0] [0xf84000ea50 0xf84000e9f0 0xf84000e9c0] [] [] 0xf8400128c0} fmt.Printf("The command is %v", cmd)
} // The command is &{/bin/ls [ls -l] [] <nil> <nil> <nil> 0xf840000210 <nil> true [0xf84000ea50 0xf84000e9f0 0xf84000e9c0] [0xf84000ea50 0xf84000e9f0 0xf84000e9c0] [] [] 0xf8400128c0}
// in Windows: uitvoering: Error fork/exec /bin/ls: The system cannot find the path specified. starting process! }
// in Windows: uitvoering: Error fork/exec /bin/ls: The system cannot find the path specified. starting process!

View File

@@ -1,9 +1,9 @@
package main package main
import "fmt" import "fmt"
func main() { func main() {
fmt.Println("Starting the program") fmt.Println("Starting the program")
panic("A severe error occurred: stopping the program!") panic("A severe error occurred: stopping the program!")
fmt.Println("Ending the program") fmt.Println("Ending the program")
} }

View File

@@ -1,39 +1,40 @@
// panic_package.go // panic_package.go
package main package main
import ( import (
"fmt" "./parse/parse"
"./parse/parse" "fmt"
) )
func main() { func main() {
var examples = []string{ var examples = []string{
"1 2 3 4 5", "1 2 3 4 5",
"100 50 25 12.5 6.25", "100 50 25 12.5 6.25",
"2 + 2 = 4", "2 + 2 = 4",
"1st class", "1st class",
"", "",
} }
for _, ex := range examples { for _, ex := range examples {
fmt.Printf("Parsing %q:\n ", ex) fmt.Printf("Parsing %q:\n ", ex)
nums, err := parse.Parse(ex) nums, err := parse.Parse(ex)
if err != nil { if err != nil {
fmt.Println(err) // here String() method from ParseError is used fmt.Println(err) // here String() method from ParseError is used
continue continue
} }
fmt.Println(nums) fmt.Println(nums)
} }
} }
/* Output:
Parsing "1 2 3 4 5": /* Output:
[1 2 3 4 5] Parsing "1 2 3 4 5":
Parsing "100 50 25 12.5 6.25": [1 2 3 4 5]
pkg parse: error parsing "12.5" as int Parsing "100 50 25 12.5 6.25":
Parsing "2 + 2 = 4": pkg parse: error parsing "12.5" as int
pkg parse: error parsing "+" as int Parsing "2 + 2 = 4":
Parsing "1st class": pkg parse: error parsing "+" as int
pkg parse: error parsing "1st" as int Parsing "1st class":
Parsing "": pkg parse: error parsing "1st" as int
pkg: no words to parse Parsing "":
*/ pkg: no words to parse
*/

View File

@@ -1,32 +1,32 @@
// panic_recover.go // panic_recover.go
package main package main
import ( import (
"fmt" "fmt"
) )
func badCall() { func badCall() {
panic("bad end") panic("bad end")
} }
func test() { func test() {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
fmt.Printf("Panicing %s\r\n", e) fmt.Printf("Panicing %s\r\n", e)
} }
}() }()
badCall() badCall()
fmt.Printf("After bad call\r\n") // <-- wordt niet bereikt fmt.Printf("After bad call\r\n") // <-- wordt niet bereikt
} }
func main() { func main() {
fmt.Printf("Calling test\r\n") fmt.Printf("Calling test\r\n")
test() test()
fmt.Printf("Test completed\r\n") fmt.Printf("Test completed\r\n")
} }
/* Output: /* Output:
Calling test Calling test
Panicing bad end Panicing bad end
Test completed Test completed
*/ */

View File

@@ -1,51 +1,51 @@
// parse.go // parse.go
package parse package parse
import ( import (
"fmt" "fmt"
"strings" "strconv"
"strconv" "strings"
) )
// A ParseError indicates an error in converting a word into an integer. // A ParseError indicates an error in converting a word into an integer.
type ParseError struct { type ParseError struct {
Index int // The index into the space-separated list of words. Index int // The index into the space-separated list of words.
Word string // The word that generated the parse error. Word string // The word that generated the parse error.
Err error // The raw error that precipitated this error, if any. Err error // The raw error that precipitated this error, if any.
} }
// String returns a human-readable error message. // String returns a human-readable error message.
func (e *ParseError) String() string { func (e *ParseError) String() string {
return fmt.Sprintf("pkg parse: error parsing %q as int", e.Word) return fmt.Sprintf("pkg parse: error parsing %q as int", e.Word)
} }
// Parse parses the space-separated words in in put as integers. // Parse parses the space-separated words in in put as integers.
func Parse(input string) (numbers []int, err error) { func Parse(input string) (numbers []int, err error) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
var ok bool var ok bool
err, ok = r.(error) err, ok = r.(error)
if !ok { if !ok {
err = fmt.Errorf("pkg: %v", r) err = fmt.Errorf("pkg: %v", r)
} }
} }
}() }()
fields := strings.Fields(input) fields := strings.Fields(input)
numbers = fields2numbers(fields) numbers = fields2numbers(fields)
return return
} }
func fields2numbers(fields []string) (numbers []int) { func fields2numbers(fields []string) (numbers []int) {
if len(fields) == 0 { if len(fields) == 0 {
panic("no words to parse") panic("no words to parse")
} }
for idx, field := range fields { for idx, field := range fields {
num, err := strconv.Atoi(field) num, err := strconv.Atoi(field)
if err != nil { if err != nil {
panic(&ParseError{idx, field, err}) panic(&ParseError{idx, field, err})
} }
numbers = append(numbers, num) numbers = append(numbers, num)
} }
return return
} }

View File

@@ -1,35 +1,35 @@
package main package main
import ( import (
"fmt" "fmt"
"testing" "testing"
) )
func main() { func main() {
fmt.Println(" sync", testing.Benchmark(BenchmarkChannelSync).String()) fmt.Println(" sync", testing.Benchmark(BenchmarkChannelSync).String())
fmt.Println("buffered", testing.Benchmark(BenchmarkChannelBuffered).String()) fmt.Println("buffered", testing.Benchmark(BenchmarkChannelBuffered).String())
} }
func BenchmarkChannelSync(b *testing.B) { func BenchmarkChannelSync(b *testing.B) {
ch := make(chan int) ch := make(chan int)
go func() { go func() {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ch <- i ch <- i
} }
close(ch) close(ch)
}() }()
for _ = range ch { for range ch {
} }
} }
func BenchmarkChannelBuffered(b *testing.B) { func BenchmarkChannelBuffered(b *testing.B) {
ch := make(chan int, 128) ch := make(chan int, 128)
go func() { go func() {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ch <- i ch <- i
} }
close(ch) close(ch)
}() }()
for _ = range ch { for range ch {
} }
} }

View File

@@ -7,7 +7,7 @@ import (
var ngoroutine = flag.Int("n", 100000, "how many goroutines") var ngoroutine = flag.Int("n", 100000, "how many goroutines")
func f(left, right chan int) { left <- 1+<-right } func f(left, right chan int) { left <- 1 + <-right }
func main() { func main() {
flag.Parse() flag.Parse()
@@ -17,7 +17,7 @@ func main() {
left, right = right, make(chan int) left, right = right, make(chan int)
go f(left, right) go f(left, right)
} }
right <- 0 // bang! right <- 0 // bang!
x := <-leftmost // wait for completion x := <-leftmost // wait for completion
fmt.Println(x) // 100000, ongeveer 1,5 s fmt.Println(x) // 100000, ongeveer 1,5 s
} }

View File

@@ -1,16 +1,15 @@
package main package main
import "fmt" import "fmt"
func main() { func main() {
ch1 := make(chan int) ch1 := make(chan int)
go pump(ch1) // pump hangs go pump(ch1) // pump hangs
fmt.Println(<-ch1) // prints only 0 fmt.Println(<-ch1) // prints only 0
} }
func pump(ch chan int) { func pump(ch chan int) {
for i := 0; ; i++ { for i := 0; ; i++ {
ch <- i ch <- i
} }
} }

View File

@@ -1,25 +1,25 @@
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
func main() { func main() {
ch1 := make(chan int) ch1 := make(chan int)
go pump(ch1) go pump(ch1)
go suck(ch1) // tons of numbers appear go suck(ch1) // tons of numbers appear
time.Sleep(1e9) time.Sleep(1e9)
} }
func pump(ch chan int) { func pump(ch chan int) {
for i := 0; ; i++ { for i := 0; ; i++ {
ch <- i ch <- i
} }
} }
func suck(ch chan int) { func suck(ch chan int) {
for { for {
fmt.Println(<-ch) fmt.Println(<-ch)
} }
} }

View File

@@ -1,29 +1,29 @@
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
func main() { func main() {
suck(pump()) suck(pump())
time.Sleep(1e9) time.Sleep(1e9)
} }
func pump() chan int { func pump() chan int {
ch := make(chan int) ch := make(chan int)
go func() { go func() {
for i := 0; ; i++ { for i := 0; ; i++ {
ch <- i ch <- i
} }
}() }()
return ch return ch
} }
func suck(ch chan int) { func suck(ch chan int) {
go func() { go func() {
for v := range ch { for v := range ch {
fmt.Println(v) fmt.Println(v)
} }
}() }()
} }

View File

@@ -1,54 +1,55 @@
// conc_access.go // conc_access.go
package main package main
import ( import (
"fmt" "fmt"
"strconv" "strconv"
) )
type Person struct { type Person struct {
Name string Name string
salary float64 salary float64
chF chan func() chF chan func()
} }
func NewPerson(name string, salary float64) *Person { func NewPerson(name string, salary float64) *Person {
p := &Person{name, salary, make(chan func())} p := &Person{name, salary, make(chan func())}
go p.backend() go p.backend()
return p return p
} }
func (p *Person) backend() { func (p *Person) backend() {
for f := range p.chF { for f := range p.chF {
f() f()
} }
} }
// Set salary. // Set salary.
func (p *Person) SetSalary(sal float64) { func (p *Person) SetSalary(sal float64) {
p.chF <- func() { p.salary = sal } p.chF <- func() { p.salary = sal }
} }
// Retrieve salary. // Retrieve salary.
func (p *Person) Salary() float64 { func (p *Person) Salary() float64 {
fChan := make(chan float64) fChan := make(chan float64)
p.chF <- func() { fChan <- p.salary } p.chF <- func() { fChan <- p.salary }
return <-fChan return <-fChan
} }
func (p *Person) String() string { func (p *Person) String() string {
return "Person - name is: " + p.Name + " - salary is: " + strconv.FormatFloat(p.Salary(), 'f', 2, 64) return "Person - name is: " + p.Name + " - salary is: " + strconv.FormatFloat(p.Salary(), 'f', 2, 64)
} }
func main() { func main() {
bs := NewPerson("Smith Bill", 2500.5) bs := NewPerson("Smith Bill", 2500.5)
fmt.Println(bs) fmt.Println(bs)
bs.SetSalary(4000.25) bs.SetSalary(4000.25)
fmt.Println("Salary changed:") fmt.Println("Salary changed:")
fmt.Println(bs) fmt.Println(bs)
} }
/* Output:
Person - name is: Smith Bill - salary is: 2500.50 /* Output:
Salary changed: Person - name is: Smith Bill - salary is: 2500.50
Person - name is: Smith Bill - salary is: 4000.25 Salary changed:
*/ Person - name is: Smith Bill - salary is: 4000.25
*/

View File

@@ -1,57 +1,58 @@
package main package main
import ( import (
"fmt" "fmt"
) )
type Any interface{} type Any interface{}
type EvalFunc func(Any) (Any, Any) type EvalFunc func(Any) (Any, Any)
func main() { func main() {
evenFunc := func(state Any) (Any, Any) { evenFunc := func(state Any) (Any, Any) {
os := state.(int) os := state.(int)
ns := os + 2 ns := os + 2
return os, ns return os, ns
} }
even := BuildLazyIntEvaluator(evenFunc, 0) even := BuildLazyIntEvaluator(evenFunc, 0)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
fmt.Printf("%vth even: %v\n", i, even()) fmt.Printf("%vth even: %v\n", i, even())
} }
} }
func BuildLazyEvaluator(evalFunc EvalFunc, initState Any) func() Any { func BuildLazyEvaluator(evalFunc EvalFunc, initState Any) func() Any {
retValChan := make(chan Any) retValChan := make(chan Any)
loopFunc := func() { loopFunc := func() {
var actState Any = initState var actState Any = initState
var retVal Any var retVal Any
for { for {
retVal, actState = evalFunc(actState) retVal, actState = evalFunc(actState)
retValChan <- retVal retValChan <- retVal
} }
} }
retFunc := func() Any { retFunc := func() Any {
return <-retValChan return <-retValChan
} }
go loopFunc() go loopFunc()
return retFunc return retFunc
} }
func BuildLazyIntEvaluator(evalFunc EvalFunc, initState Any) func() int { func BuildLazyIntEvaluator(evalFunc EvalFunc, initState Any) func() int {
ef := BuildLazyEvaluator(evalFunc, initState) ef := BuildLazyEvaluator(evalFunc, initState)
return func() int { return func() int {
return ef().(int) return ef().(int)
} }
} }
/* Output:
0th even: 0 /* Output:
1th even: 2 0th even: 0
2th even: 4 1th even: 2
3th even: 6 2th even: 4
4th even: 8 3th even: 6
5th even: 10 4th even: 8
6th even: 12 5th even: 10
7th even: 14 6th even: 12
8th even: 16 7th even: 14
9th even: 18 8th even: 16
*/ 9th even: 18
*/

View File

@@ -1,29 +1,29 @@
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
func main() { func main() {
fmt.Println("In main()") fmt.Println("In main()")
// longWait() // longWait()
go longWait() go longWait()
// shortWait() // shortWait()
go shortWait() go shortWait()
fmt.Println("About to sleep in main()") fmt.Println("About to sleep in main()")
time.Sleep(10 * 1e9) // sleep works with a Duration in nanoseconds (ns) ! time.Sleep(10 * 1e9) // sleep works with a Duration in nanoseconds (ns) !
fmt.Println("At the end of main()") fmt.Println("At the end of main()")
} }
func longWait() { func longWait() {
fmt.Println("Beginning longWait()") fmt.Println("Beginning longWait()")
time.Sleep(5 * 1e9) // sleep for 5 seconds time.Sleep(5 * 1e9) // sleep for 5 seconds
fmt.Println("End of longWait()") fmt.Println("End of longWait()")
} }
func shortWait() { func shortWait() {
fmt.Println("Beginning shortWait()") fmt.Println("Beginning shortWait()")
time.Sleep(2 * 1e9) // sleep for 2 seconds time.Sleep(2 * 1e9) // sleep for 2 seconds
fmt.Println("End of shortWait()") fmt.Println("End of shortWait()")
} }

View File

@@ -1,33 +1,34 @@
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
func main() { func main() {
ch := make(chan string) ch := make(chan string)
go sendData(ch) go sendData(ch)
go getData(ch) go getData(ch)
time.Sleep(1e9) time.Sleep(1e9)
} }
func sendData(ch chan string) { func sendData(ch chan string) {
ch <- "Washington" ch <- "Washington"
ch <- "Tripoli" ch <- "Tripoli"
ch <- "London" ch <- "London"
ch <- "Beijing" ch <- "Beijing"
ch <- "Tokio" ch <- "Tokio"
} }
func getData(ch chan string) { func getData(ch chan string) {
var input string var input string
// time.Sleep(1e9) // time.Sleep(1e9)
for { for {
input = <-ch input = <-ch
fmt.Printf("%s ", input) fmt.Printf("%s ", input)
} }
} }
// Washington Tripoli London Beijing Tokio
// Washington Tripoli London Beijing Tokio

View File

@@ -1,29 +1,30 @@
package main package main
import "fmt" import "fmt"
func main() { func main() {
ch := make(chan string) ch := make(chan string)
go sendData(ch) go sendData(ch)
getData(ch) getData(ch)
} }
func sendData(ch chan string) { func sendData(ch chan string) {
ch <- "Washington" ch <- "Washington"
ch <- "Tripoli" ch <- "Tripoli"
ch <- "London" ch <- "London"
ch <- "Beijing" ch <- "Beijing"
ch <- "Tokio" ch <- "Tokio"
close(ch) close(ch)
} }
func getData(ch chan string) { func getData(ch chan string) {
for { for {
input, open := <-ch input, open := <-ch
if !open { if !open {
break break
} }
fmt.Printf("%s ", input) fmt.Printf("%s ", input)
} }
} }
// Washington Tripoli London Beijing Tokio
// Washington Tripoli London Beijing Tokio

View File

@@ -1,40 +1,40 @@
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
func main() { func main() {
ch1 := make(chan int) ch1 := make(chan int)
ch2 := make(chan int) ch2 := make(chan int)
go pump1(ch1) go pump1(ch1)
go pump2(ch2) go pump2(ch2)
go suck(ch1, ch2) go suck(ch1, ch2)
time.Sleep(1e9) time.Sleep(1e9)
} }
func pump1(ch chan int) { func pump1(ch chan int) {
for i := 0; ; i++ { for i := 0; ; i++ {
ch <- i * 2 ch <- i * 2
} }
} }
func pump2(ch chan int) { func pump2(ch chan int) {
for i := 0; ; i++ { for i := 0; ; i++ {
ch <- i + 5 ch <- i + 5
} }
} }
func suck(ch1, ch2 chan int) { func suck(ch1, ch2 chan int) {
for { for {
select { select {
case v := <-ch1: case v := <-ch1:
fmt.Printf("Received on channel 1: %d\n", v) fmt.Printf("Received on channel 1: %d\n", v)
case v := <-ch2: case v := <-ch2:
fmt.Printf("Received on channel 2: %d\n", v) fmt.Printf("Received on channel 2: %d\n", v)
} }
} }
} }

View File

@@ -1,49 +1,47 @@
package main package main
import ( import (
"fmt" "fmt"
"time" "runtime"
"runtime" "time"
) )
func main() { func main() {
// setting GOMAXPROCS to 2 gives +- 22% performance increase, // setting GOMAXPROCS to 2 gives +- 22% performance increase,
// but increasing the number doesn't increase the performance // but increasing the number doesn't increase the performance
// without GOMAXPROCS: +- 86000 // without GOMAXPROCS: +- 86000
// setting GOMAXPROCS to 2: +- 105000 // setting GOMAXPROCS to 2: +- 105000
// setting GOMAXPROCS to 3: +- 94000 // setting GOMAXPROCS to 3: +- 94000
runtime.GOMAXPROCS(2) runtime.GOMAXPROCS(2)
ch1 := make(chan int) ch1 := make(chan int)
ch2 := make(chan int) ch2 := make(chan int)
go pump1(ch1) go pump1(ch1)
go pump2(ch2) go pump2(ch2)
go suck(ch1, ch2) go suck(ch1, ch2)
time.Sleep(1e9) time.Sleep(1e9)
} }
func pump1(ch chan int) { func pump1(ch chan int) {
for i:=0; ; i++ { for i := 0; ; i++ {
ch <- i*2 ch <- i * 2
} }
} }
func pump2(ch chan int) { func pump2(ch chan int) {
for i:=0; ; i++ { for i := 0; ; i++ {
ch <- i+5 ch <- i + 5
} }
} }
func suck(ch1,ch2 chan int) { func suck(ch1, ch2 chan int) {
for i := 0; ; i++ { for i := 0; ; i++ {
select { select {
case v := <- ch1: case v := <-ch1:
fmt.Printf("%d - Received on channel 1: %d\n", i, v) fmt.Printf("%d - Received on channel 1: %d\n", i, v)
case v := <- ch2: case v := <-ch2:
fmt.Printf("%d - Received on channel 2: %d\n", i, v) fmt.Printf("%d - Received on channel 2: %d\n", i, v)
} }
} }
} }

View File

@@ -1,30 +1,30 @@
// lazy_evaluation.go // lazy_evaluation.go
package main package main
import ( import (
"fmt" "fmt"
) )
var resume chan int var resume chan int
func integers() chan int { func integers() chan int {
yield := make (chan int) yield := make(chan int)
count := 0 count := 0
go func () { go func() {
for { for {
yield <- count yield <- count
count++ count++
} }
} () }()
return yield return yield
} }
func generateInteger() int { func generateInteger() int {
return <-resume return <-resume
} }
func main() { func main() {
resume = integers() resume = integers()
fmt.Println(generateInteger()) //=> 0 fmt.Println(generateInteger()) //=> 0
fmt.Println(generateInteger()) //=> 1 fmt.Println(generateInteger()) //=> 1
fmt.Println(generateInteger()) //=> 2 fmt.Println(generateInteger()) //=> 2
} }

View File

@@ -1,31 +1,32 @@
package main package main
const MAXREQS = 50 const MAXREQS = 50
var sem = make(chan int, MAXREQS)
var sem = make(chan int, MAXREQS)
type Request struct {
a, b int type Request struct {
replyc chan int a, b int
} replyc chan int
}
func process(r *Request) {
// do something func process(r *Request) {
} // do something
}
func handle(r *Request) {
sem <- 1 // doesn't matter what we put in it func handle(r *Request) {
process(r) sem <- 1 // doesn't matter what we put in it
<-sem // one empty place in the buffer: the next request can start process(r)
} <-sem // one empty place in the buffer: the next request can start
}
func server(service chan *Request) {
for { func server(service chan *Request) {
request := <-service for {
go handle(request) request := <-service
} go handle(request)
} }
}
func main() {
service := make(chan *Request) func main() {
go server(service) service := make(chan *Request)
} go server(service)
}

View File

@@ -1,53 +1,53 @@
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package main package main
import "fmt" import "fmt"
type Request struct { type Request struct {
a, b int a, b int
replyc chan int // reply channel inside the Request replyc chan int // reply channel inside the Request
} }
type binOp func(a, b int) int type binOp func(a, b int) int
func run(op binOp, req *Request) { func run(op binOp, req *Request) {
req.replyc <- op(req.a, req.b) req.replyc <- op(req.a, req.b)
} }
func server(op binOp, service chan *Request) { func server(op binOp, service chan *Request) {
for { for {
req := <-service // requests arrive here req := <-service // requests arrive here
// start goroutine for request: // start goroutine for request:
go run(op, req) // don't wait for op go run(op, req) // don't wait for op
} }
} }
func startServer(op binOp) chan *Request { func startServer(op binOp) chan *Request {
reqChan := make(chan *Request) reqChan := make(chan *Request)
go server(op, reqChan) go server(op, reqChan)
return reqChan return reqChan
} }
func main() { func main() {
adder := startServer(func(a, b int) int { return a + b }) adder := startServer(func(a, b int) int { return a + b })
const N = 100 const N = 100
var reqs [N]Request var reqs [N]Request
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
req := &reqs[i] req := &reqs[i]
req.a = i req.a = i
req.b = i + N req.b = i + N
req.replyc = make(chan int) req.replyc = make(chan int)
adder <- req adder <- req
} }
// checks: // checks:
for i := N - 1; i >= 0; i-- { // doesn't matter what order for i := N - 1; i >= 0; i-- { // doesn't matter what order
if <-reqs[i].replyc != N+2*i { if <-reqs[i].replyc != N+2*i {
fmt.Println("fail at", i) fmt.Println("fail at", i)
} else { } else {
fmt.Println("Request ", i, " is ok!") fmt.Println("Request ", i, " is ok!")
} }
} }
fmt.Println("done") fmt.Println("done")
} }

View File

@@ -1,58 +1,58 @@
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package main package main
import "fmt" import "fmt"
type Request struct { type Request struct {
a, b int a, b int
replyc chan int // reply channel inside the Request replyc chan int // reply channel inside the Request
} }
type binOp func(a, b int) int type binOp func(a, b int) int
func run(op binOp, req *Request) { func run(op binOp, req *Request) {
req.replyc <- op(req.a, req.b) req.replyc <- op(req.a, req.b)
} }
func server(op binOp, service chan *Request, quit chan bool) { func server(op binOp, service chan *Request, quit chan bool) {
for { for {
select { select {
case req := <-service: case req := <-service:
go run(op, req) go run(op, req)
case <-quit: case <-quit:
return return
} }
} }
} }
func startServer(op binOp) (service chan *Request, quit chan bool) { func startServer(op binOp) (service chan *Request, quit chan bool) {
service = make(chan *Request) service = make(chan *Request)
quit = make(chan bool) quit = make(chan bool)
go server(op, service, quit) go server(op, service, quit)
return service, quit return service, quit
} }
func main() { func main() {
adder, quit := startServer(func(a, b int) int { return a + b }) adder, quit := startServer(func(a, b int) int { return a + b })
const N = 100 const N = 100
var reqs [N]Request var reqs [N]Request
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
req := &reqs[i] req := &reqs[i]
req.a = i req.a = i
req.b = i + N req.b = i + N
req.replyc = make(chan int) req.replyc = make(chan int)
adder <- req adder <- req
} }
// checks: // checks:
for i := N - 1; i >= 0; i-- { // doesn't matter what order for i := N - 1; i >= 0; i-- { // doesn't matter what order
if <-reqs[i].replyc != N+2*i { if <-reqs[i].replyc != N+2*i {
fmt.Println("fail at", i) fmt.Println("fail at", i)
} else { } else {
fmt.Println("Request ", i, " is ok!") fmt.Println("Request ", i, " is ok!")
} }
} }
quit <- true quit <- true
fmt.Println("done") fmt.Println("done")
} }

View File

@@ -1,37 +1,37 @@
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.package main // license that can be found in the LICENSE file.package main
package main package main
import "fmt" import "fmt"
// Send the sequence 2, 3, 4, ... to channel 'ch'. // Send the sequence 2, 3, 4, ... to channel 'ch'.
func generate(ch chan int) { func generate(ch chan int) {
for i := 2; ; i++ { for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'. ch <- i // Send 'i' to channel 'ch'.
} }
} }
// Copy the values from channel 'in' to channel 'out', // Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'. // removing those divisible by 'prime'.
func filter(in, out chan int, prime int) { func filter(in, out chan int, prime int) {
for { for {
i := <-in // Receive value of new variable 'i' from 'in'. i := <-in // Receive value of new variable 'i' from 'in'.
if i%prime != 0 { if i%prime != 0 {
out <- i // Send 'i' to channel 'out'. out <- i // Send 'i' to channel 'out'.
} }
} }
} }
// The prime sieve: Daisy-chain filter processes together. // The prime sieve: Daisy-chain filter processes together.
func main() { func main() {
ch := make(chan int) // Create a new channel. ch := make(chan int) // Create a new channel.
go generate(ch) // Start generate() as a goroutine. go generate(ch) // Start generate() as a goroutine.
for { for {
prime := <-ch prime := <-ch
fmt.Print(prime, " ") fmt.Print(prime, " ")
ch1 := make(chan int) ch1 := make(chan int)
go filter(ch, ch1, prime) go filter(ch, ch1, prime)
ch = ch1 ch = ch1
} }
} }

View File

@@ -1,53 +1,53 @@
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package main package main
import ( import (
"fmt" "fmt"
) )
// Send the sequence 2, 3, 4, ... to returned channel // Send the sequence 2, 3, 4, ... to returned channel
func generate() chan int { func generate() chan int {
ch := make(chan int) ch := make(chan int)
go func() { go func() {
for i := 2; ; i++ { for i := 2; ; i++ {
ch <- i ch <- i
} }
}() }()
return ch return ch
} }
// Filter out input values divisible by 'prime', send rest to returned channel // Filter out input values divisible by 'prime', send rest to returned channel
func filter(in chan int, prime int) chan int { func filter(in chan int, prime int) chan int {
out := make(chan int) out := make(chan int)
go func() { go func() {
for { for {
if i := <-in; i%prime != 0 { if i := <-in; i%prime != 0 {
out <- i out <- i
} }
} }
}() }()
return out return out
} }
func sieve() chan int { func sieve() chan int {
out := make(chan int) out := make(chan int)
go func() { go func() {
ch := generate() ch := generate()
for { for {
prime := <-ch prime := <-ch
ch = filter(ch, prime) ch = filter(ch, prime)
out <- prime out <- prime
} }
}() }()
return out return out
} }
func main() { func main() {
primes := sieve() primes := sieve()
for { for {
fmt.Println(<-primes) fmt.Println(<-primes)
} }
} }

View File

@@ -1,42 +1,43 @@
// default.go // default.go
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
func main() { func main() {
tick := time.Tick(1e8) tick := time.Tick(1e8)
boom := time.After(5e8) boom := time.After(5e8)
for { for {
select { select {
case <-tick: case <-tick:
fmt.Println("tick.") fmt.Println("tick.")
case <-boom: case <-boom:
fmt.Println("BOOM!") fmt.Println("BOOM!")
return return
default: default:
fmt.Println(" .") fmt.Println(" .")
time.Sleep(5e7) time.Sleep(5e7)
} }
} }
} }
/* Output:
. /* Output:
. .
tick. .
. tick.
. .
tick. .
. tick.
. .
tick. .
. tick.
. .
tick. .
. tick.
. .
tick. .
BOOM! tick.
*/ BOOM!
*/

View File

@@ -1,47 +1,48 @@
// closures_goroutines.go // closures_goroutines.go
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
var values = [5]int{10, 11, 12, 13, 14} var values = [5]int{10, 11, 12, 13, 14}
func main() { func main() {
// version A: // version A:
for ix := range values { // ix is index! for ix := range values { // ix is index!
func() { func() {
fmt.Print(ix, " ") fmt.Print(ix, " ")
}() // call closure, prints each index }() // call closure, prints each index
} }
fmt.Println() fmt.Println()
// version B: same as A, but call closure as a goroutine // version B: same as A, but call closure as a goroutine
for ix := range values { for ix := range values {
go func() { go func() {
fmt.Print(ix, " ") fmt.Print(ix, " ")
}() }()
} }
time.Sleep(1e9) time.Sleep(1e9)
// version C: the right way // version C: the right way
for ix := range values { for ix := range values {
go func(ix interface{}) { go func(ix interface{}) {
fmt.Print(ix, " ") fmt.Print(ix, " ")
}(ix) }(ix)
} }
time.Sleep(1e9) time.Sleep(1e9)
// version D: print out the values: // version D: print out the values:
for ix := range values { for ix := range values {
val := values[ix] val := values[ix]
go func() { go func() {
fmt.Print(val, " ") fmt.Print(val, " ")
}() }()
} }
time.Sleep(1e9) time.Sleep(1e9)
} }
/* Output:
0 1 2 3 4 /* Output:
4 4 4 4 4 0 1 2 3 4
1 0 3 4 2 4 4 4 4 4
0 1 2 4 3 1 0 3 4 2
*/ 0 1 2 4 3
*/

View File

@@ -1,31 +1,30 @@
// nexter.go // nexter.go
package main package main
import ( import (
"fmt" "fmt"
) )
type nexter interface { type nexter interface {
next() byte next() byte
} }
func nextFew1(n nexter, num int) []byte {
func nextFew1(n nexter, num int) []byte { var b []byte
var b []byte for i := 0; i < num; i++ {
for i:=0; i < num; i++ { b[i] = n.next()
b[i] = n.next() }
} return b
return b }
}
func nextFew2(n *nexter, num int) []byte {
func nextFew2(n *nexter, num int) []byte { var b []byte
var b []byte for i := 0; i < num; i++ {
for i:=0; i < num; i++ { b[i] = n.next() // compile error: n.next undefined (type *nexter has no field or method next)
b[i] = n.next() // compile error: n.next undefined (type *nexter has no field or method next) }
} return b
return b }
}
func main() {
func main() { fmt.Println("Hello World!")
fmt.Println("Hello World!") }
}

View File

@@ -11,6 +11,7 @@ URL: <input type="text" name="url">
<input type="submit" value="Add"> <input type="submit" value="Add">
</form> </form>
` `
var store = NewURLStore() var store = NewURLStore()
func main() { func main() {
@@ -29,7 +30,6 @@ func Redirect(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, url, http.StatusFound) http.Redirect(w, r, url, http.StatusFound)
} }
func Add(w http.ResponseWriter, r *http.Request) { func Add(w http.ResponseWriter, r *http.Request) {
url := r.FormValue("url") url := r.FormValue("url")
if url == "" { if url == "" {

View File

@@ -3,8 +3,8 @@ package main
import "sync" import "sync"
type URLStore struct { type URLStore struct {
urls map[string]string urls map[string]string
mu sync.RWMutex mu sync.RWMutex
} }
func NewURLStore() *URLStore { func NewURLStore() *URLStore {

View File

@@ -23,7 +23,6 @@ func Redirect(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, url, http.StatusFound) http.Redirect(w, r, url, http.StatusFound)
} }
func Add(w http.ResponseWriter, r *http.Request) { func Add(w http.ResponseWriter, r *http.Request) {
url := r.FormValue("url") url := r.FormValue("url")
if url == "" { if url == "" {

View File

@@ -9,9 +9,9 @@ import (
) )
type URLStore struct { type URLStore struct {
urls map[string]string urls map[string]string
mu sync.RWMutex mu sync.RWMutex
file *os.File file *os.File
} }
type record struct { type record struct {
@@ -70,7 +70,7 @@ func (s *URLStore) load() error {
if _, err := s.file.Seek(0, 0); err != nil { if _, err := s.file.Seek(0, 0); err != nil {
return err return err
} }
d := gob.NewDecoder(s.file) d := gob.NewDecoder(s.file)
var err error var err error
for err == nil { for err == nil {
var r record var r record

View File

@@ -1,7 +1,7 @@
package main package main
import ( import (
// "bufio" // "bufio"
"encoding/gob" "encoding/gob"
"io" "io"
"log" "log"
@@ -12,9 +12,9 @@ import (
const saveQueueLength = 1000 const saveQueueLength = 1000
type URLStore struct { type URLStore struct {
urls map[string]string urls map[string]string
mu sync.RWMutex mu sync.RWMutex
save chan record save chan record
} }
type record struct { type record struct {
@@ -74,9 +74,9 @@ func (s *URLStore) load(filename string) error {
} }
defer f.Close() defer f.Close()
// buffered reading: // buffered reading:
// b := bufio.NewReader(f) // b := bufio.NewReader(f)
// d := gob.NewDecoder(b) // d := gob.NewDecoder(b)
d := gob.NewDecoder(f) d := gob.NewDecoder(f)
for err == nil { for err == nil {
var r record var r record
if err = d.Decode(&r); err == nil { if err = d.Decode(&r); err == nil {
@@ -97,13 +97,13 @@ func (s *URLStore) saveLoop(filename string) {
log.Fatal("Error opening URLStore: ", err) log.Fatal("Error opening URLStore: ", err)
} }
defer f.Close() defer f.Close()
e := gob.NewEncoder(f) e := gob.NewEncoder(f)
// buffered encoding: // buffered encoding:
// b := bufio.NewWriter(f) // b := bufio.NewWriter(f)
// e := gob.NewEncoder(b) // e := gob.NewEncoder(b)
// defer b.Flush() // defer b.Flush()
for { for {
r := <-s.save // takes a record from the channel r := <-s.save // takes a record from the channel
if err := e.Encode(r); err != nil { if err := e.Encode(r); err != nil {
log.Println("Error saving to URLStore: ", err) log.Println("Error saving to URLStore: ", err)
} }

View File

@@ -11,9 +11,9 @@ import (
const saveQueueLength = 1000 const saveQueueLength = 1000
type URLStore struct { type URLStore struct {
urls map[string]string urls map[string]string
mu sync.RWMutex mu sync.RWMutex
save chan record save chan record
} }
type record struct { type record struct {
@@ -72,7 +72,7 @@ func (s *URLStore) load(filename string) error {
return err return err
} }
defer f.Close() defer f.Close()
d := json.NewDecoder(f) d := json.NewDecoder(f)
for err == nil { for err == nil {
var r record var r record
if err = d.Decode(&r); err == nil { if err = d.Decode(&r); err == nil {
@@ -93,9 +93,9 @@ func (s *URLStore) saveLoop(filename string) {
log.Fatal("Error opening URLStore: ", err) log.Fatal("Error opening URLStore: ", err)
} }
defer f.Close() defer f.Close()
e := json.NewEncoder(f) e := json.NewEncoder(f)
for { for {
r := <-s.save // takes a record from the channel r := <-s.save // takes a record from the channel
if err := e.Encode(r); err != nil { if err := e.Encode(r); err != nil {
log.Println("Error saving to URLStore: ", err) log.Println("Error saving to URLStore: ", err)
} }

Some files were not shown because too many files have changed in this diff Show More