fix: coding style and file format for chapter 11, 12, 13, 14 and 15.

This commit is contained in:
Bo-Yi Wu
2017-02-11 12:32:16 +08:00
parent c5413075c1
commit 4abbfabb52
63 changed files with 2662 additions and 2622 deletions

View File

@@ -1,66 +1,66 @@
package float64 package float64
import ( import (
"fmt" "fmt"
"math/rand" "math/rand"
"time" "time"
) )
type Sorter interface { type Sorter interface {
Len() int Len() int
Less(i, j int) bool Less(i, j int) bool
Swap(i, j int) Swap(i, j int)
} }
func Sort(data Sorter) { func Sort(data Sorter) {
for pass := 1; pass < data.Len(); pass++ { for pass := 1; pass < data.Len(); pass++ {
for i := 0; i < data.Len()-pass; i++ { for i := 0; i < data.Len()-pass; i++ {
if data.Less(i+1, i) { if data.Less(i+1, i) {
data.Swap(i, i+1) data.Swap(i, i+1)
} }
} }
} }
} }
func IsSorted(data Sorter) bool { func IsSorted(data Sorter) 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
} }
type Float64Array []float64 type Float64Array []float64
func (p Float64Array) Len() int { return len(p) } func (p Float64Array) Len() int { return len(p) }
func (p Float64Array) Less(i, j int) bool { return p[i] < p[j] } 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] } func (p Float64Array) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func NewFloat64Array() Float64Array { func NewFloat64Array() Float64Array {
return make([]float64, 25) return make([]float64, 25)
} }
func (p Float64Array) Fill(n int) { func (p Float64Array) Fill(n int) {
rand.Seed(int64(time.Now().Nanosecond())) rand.Seed(int64(time.Now().Nanosecond()))
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
p[i] = 100 * (rand.Float64()) p[i] = 100 * (rand.Float64())
} }
} }
func (p Float64Array) List() string { func (p Float64Array) List() string {
s := "{ " s := "{ "
for i := 0; i < p.Len(); i++ { for i := 0; i < p.Len(); i++ {
if p[i] == 0 { if p[i] == 0 {
continue continue
} }
s += fmt.Sprintf("%3.1f ", p[i]) s += fmt.Sprintf("%3.1f ", p[i])
} }
s += " }" s += " }"
return s return s
} }
func (p Float64Array) String() string { func (p Float64Array) String() string {
return p.List() return p.List()
} }

View File

@@ -1,25 +1,25 @@
package main package main
import ( import (
"fmt" "./float64"
"./float64" "fmt"
) )
func main() { func main() {
f1 := float64.NewFloat64Array() f1 := float64.NewFloat64Array()
f1.Fill(10) f1.Fill(10)
fmt.Printf("Before sorting %s\n", f1) fmt.Printf("Before sorting %s\n", f1)
float64.Sort(f1) float64.Sort(f1)
fmt.Printf("After sorting %s\n", f1) fmt.Printf("After sorting %s\n", f1)
if float64.IsSorted(f1) { if float64.IsSorted(f1) {
fmt.Println("The float64 array is sorted!") fmt.Println("The float64 array is sorted!")
} else { } else {
fmt.Println("The float64 array is NOT sorted!") fmt.Println("The float64 array is NOT sorted!")
} }
} }
/* Output: /* Output:
Before sorting { 55.0 82.3 36.4 66.6 25.3 82.7 47.4 21.5 4.6 81.6 } Before sorting { 55.0 82.3 36.4 66.6 25.3 82.7 47.4 21.5 4.6 81.6 }
After sorting { 4.6 21.5 25.3 36.4 47.4 55.0 66.6 81.6 82.3 82.7 } After sorting { 4.6 21.5 25.3 36.4 47.4 55.0 66.6 81.6 82.3 82.7 }
The float64 array is sorted! The float64 array is sorted!
*/ */

View File

@@ -1,46 +1,46 @@
// interface_nil.go // interface_nil.go
package main package main
import "fmt" import "fmt"
type Any interface {} type Any interface{}
type Anything struct {} type Anything struct{}
func main() { func main() {
any := getAny() any := getAny()
if any == nil { if any == nil {
fmt.Println("any is nil") fmt.Println("any is nil")
} else { } else {
fmt.Println("any is not nil") fmt.Println("any is not nil")
} }
/* /*
// to get the inner value: // to get the inner value:
anything := any.(*Anything) anything := any.(*Anything)
if anything == nil { if anything == nil {
fmt.Println("anything is nil") fmt.Println("anything is nil")
} else { } else {
fmt.Println("anything is not nil") fmt.Println("anything is not nil")
} }
*/ */
} }
func getAny() Any { func getAny() Any {
return getAnything() return getAnything()
} }
func getAnything() *Anything { func getAnything() *Anything {
return nil return nil
} }
/* Output: /* Output:
any is not nil any is not nil
WHY? WHY?
you would perhaps expect: any is nil,because getAnything() returns that you would perhaps expect: any is nil,because getAnything() returns that
BUT: BUT:
the interface value any is storing a value, so it is not nil. the interface value any is storing a value, so it is not nil.
It just so happens that the particular value it is storing is a nil pointer. It just so happens that the particular value it is storing is a nil pointer.
The any variable has a type, so it's not a nil interface, The any variable has a type, so it's not a nil interface,
rather an interface variable with type Any and concrete value (*Anything)(nil). rather an interface variable with type Any and concrete value (*Anything)(nil).
To get the inner value of any, use: anything := any.(*Anything) To get the inner value of any, use: anything := any.(*Anything)
now anything contains nil ! now anything contains nil !
*/ */

View File

@@ -1,68 +1,69 @@
// interface_poly3.go // interface_poly3.go
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
) )
type Shaper interface { type Shaper interface {
Area() float32 Area() float32
} }
type Shape struct {} type Shape struct{}
func (sh Shape) Area() float32 {
return -1 // the shape is indetermined, so we return something impossible func (sh Shape) Area() float32 {
} return -1 // the shape is indetermined, so we return something impossible
}
type Square struct {
side float32 type Square struct {
Shape side float32
} Shape
}
func (sq *Square) Area() float32 {
return sq.side * sq.side func (sq *Square) Area() float32 {
} return sq.side * sq.side
}
type Rectangle struct {
length, width float32 type Rectangle struct {
Shape length, width float32
} Shape
}
func (r *Rectangle) Area() float32 {
return r.length * r.width func (r *Rectangle) Area() float32 {
} return r.length * r.width
}
type Circle struct {
radius float32 type Circle struct {
Shape radius float32
} Shape
}
func (c *Circle) Area() float32 {
return math.Pi * c.radius * c.radius func (c *Circle) Area() float32 {
} return math.Pi * c.radius * c.radius
}
func main() {
s := Shape{} func main() {
r := &Rectangle{5, 3, s} // Area() of Rectangle needs a value s := Shape{}
q := &Square{5, s} // Area() of Square needs a pointer r := &Rectangle{5, 3, s} // Area() of Rectangle needs a value
c := &Circle{2.5, s} q := &Square{5, s} // Area() of Square needs a pointer
shapes := []Shaper{r, q, c, s} c := &Circle{2.5, s}
fmt.Println("Looping through shapes for area ...") shapes := []Shaper{r, q, c, s}
for n, _ := range shapes { fmt.Println("Looping through shapes for area ...")
fmt.Println("Shape details: ", shapes[n]) for n := range shapes {
fmt.Println("Area of this shape is: ", shapes[n].Area()) fmt.Println("Shape details: ", shapes[n])
} fmt.Println("Area of this shape is: ", shapes[n].Area())
} }
/* Output: }
Looping through shapes for area ...
Shape details: {5 3} /* Output:
Area of this shape is: 15 Looping through shapes for area ...
Shape details: &{5} Shape details: {5 3}
Area of this shape is: 25 Area of this shape is: 15
Shape details: &{2.5} Shape details: &{5}
Area of this shape is: 19.634954 Area of this shape is: 25
Shape details: {} Shape details: &{2.5}
Area of this shape is: -1 Area of this shape is: 19.634954
*/ Shape details: {}
Area of this shape is: -1
*/

View File

@@ -1,51 +1,52 @@
package main package main
import "fmt" import "fmt"
type Square struct { type Square struct {
side float32 side float32
} }
type Triangle struct { type Triangle struct {
base float32 base float32
height float32 height float32
} }
type AreaInterface interface { type AreaInterface interface {
Area() float32 Area() float32
} }
type PeriInterface interface { type PeriInterface interface {
Perimeter() float32 Perimeter() float32
} }
func main() {
var areaIntf AreaInterface func main() {
var periIntf PeriInterface var areaIntf AreaInterface
var periIntf PeriInterface
sq1 := new(Square)
sq1.side = 5 sq1 := new(Square)
tr1 := new(Triangle) sq1.side = 5
tr1.base = 3 tr1 := new(Triangle)
tr1.height = 5 tr1.base = 3
tr1.height = 5
areaIntf = sq1
fmt.Printf("The square has area: %f\n", areaIntf.Area()) areaIntf = sq1
fmt.Printf("The square has area: %f\n", areaIntf.Area())
periIntf = sq1
fmt.Printf("The square has perimeter: %f\n", periIntf.Perimeter()) periIntf = sq1
fmt.Printf("The square has perimeter: %f\n", periIntf.Perimeter())
areaIntf = tr1
fmt.Printf("The triangle has area: %f\n", areaIntf.Area()) areaIntf = tr1
} fmt.Printf("The triangle has area: %f\n", areaIntf.Area())
}
func (sq *Square) Area() float32 {
return sq.side * sq.side func (sq *Square) Area() float32 {
} return sq.side * sq.side
}
func (sq *Square) Perimeter() float32 {
return 4 * sq.side func (sq *Square) Perimeter() float32 {
} return 4 * sq.side
}
func (tr *Triangle) Area() float32 {
return 0.5 * tr.base*tr.height func (tr *Triangle) Area() float32 {
} return 0.5 * tr.base * tr.height
}

View File

@@ -1,57 +1,58 @@
// interfaces_poly2.go // interfaces_poly2.go
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
) )
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
} }
type Circle struct { type Circle struct {
radius float32 radius float32
} }
func (c *Circle) Area() float32 { func (c *Circle) Area() float32 {
return math.Pi * c.radius * c.radius return math.Pi * c.radius * c.radius
} }
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
c := &Circle{2.5} c := &Circle{2.5}
fmt.Println("Looping through shapes for area ...") fmt.Println("Looping through shapes for area ...")
// shapes := []Shaper{Shaper(r), Shaper(q), Shaper(c)} // shapes := []Shaper{Shaper(r), Shaper(q), Shaper(c)}
shapes := []Shaper{r, q, c} shapes := []Shaper{r, q, c}
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}
Shape details: &{2.5} Area of this shape is: 25
Area of this shape is: 19.634954 Shape details: &{2.5}
*/ Area of this shape is: 19.634954
*/

View File

@@ -1,29 +1,30 @@
// main_stack.go // main_stack.go
package main package main
import ( import (
"fmt" "./stack/stack"
"./stack/stack" "fmt"
) )
var st1 stack.Stack var st1 stack.Stack
func main() { func main() {
st1.Push("Brown") st1.Push("Brown")
st1.Push(3.14) st1.Push(3.14)
st1.Push(100) st1.Push(100)
st1.Push([]string{"Java", "C++", "Python", "C#", "Ruby"}) st1.Push([]string{"Java", "C++", "Python", "C#", "Ruby"})
for { for {
item, err := st1.Pop() item, err := st1.Pop()
if err != nil { if err != nil {
break break
} }
fmt.Println(item) fmt.Println(item)
} }
} }
/* Output:
[Java C++ Python C# Ruby] /* Output:
100 [Java C++ Python C# Ruby]
3.14 100
Brown 3.14
*/ Brown
*/

View File

@@ -1,17 +1,17 @@
// main_stack_v2.go // main_stack_v2.go
package main package main
import ( import (
"./stack/collection" "./stack/collection"
"fmt" "fmt"
) )
func main() { func main() {
var s collection.Stack var s collection.Stack
s.Push("world") s.Push("world")
s.Push("hello, ") s.Push("hello, ")
for s.Size() > 0 { for s.Size() > 0 {
fmt.Print(s.Pop()) fmt.Print(s.Pop())
} }
fmt.Println() fmt.Println()
} }

View File

@@ -1,62 +1,63 @@
package main package main
import "fmt" import "fmt"
type obj interface{} type obj interface{}
func main() { func main() {
// define a generic lambda function mf: // define a generic lambda function mf:
mf := func(i obj) obj { mf := func(i obj) obj {
switch i.(type) { switch i.(type) {
case int: case int:
return i.(int) * 2 return i.(int) * 2
case string: case string:
return i.(string) + i.(string) return i.(string) + i.(string)
} }
return i return i
} }
isl := []obj{0, 1, 2, 3, 4, 5} isl := []obj{0, 1, 2, 3, 4, 5}
res1 := mapFunc(mf, isl) res1 := mapFunc(mf, isl)
for _, v := range res1 { for _, v := range res1 {
fmt.Println(v) fmt.Println(v)
} }
println() println()
ssl := []obj{"0", "1", "2", "3", "4", "5"} ssl := []obj{"0", "1", "2", "3", "4", "5"}
res2 := mapFunc(mf, ssl) res2 := mapFunc(mf, ssl)
for _, v := range res2 { for _, v := range res2 {
fmt.Println(v) fmt.Println(v)
} }
} }
func mapFunc(mf func(obj) obj, list []obj) ([]obj) { func mapFunc(mf func(obj) obj, list []obj) []obj {
result := make([]obj, len(list)) result := make([]obj, len(list))
for ix, v := range list { for ix, v := range list {
result[ix] = mf(v) result[ix] = mf(v)
} }
// Equivalent: // Equivalent:
/* /*
for ix := 0; ix<len(list); ix++ { for ix := 0; ix<len(list); ix++ {
result[ix] = mf(list[ix]) result[ix] = mf(list[ix])
} }
*/ */
return result return result
} }
/* Output:
0 /* Output:
2 0
4 2
6 4
8 6
10 8
10
00
11 00
22 11
33 22
44 33
55 44
*/ 55
*/

View File

@@ -1,59 +1,60 @@
package main package main
import "fmt" import "fmt"
type obj interface{} type obj interface{}
func main() { func main() {
// define a generic lambda function mf: // define a generic lambda function mf:
mf := func(i obj) obj { mf := func(i obj) obj {
switch i.(type) { switch i.(type) {
case int: case int:
return i.(int) * 2 return i.(int) * 2
case string: case string:
return i.(string) + i.(string) return i.(string) + i.(string)
} }
return i return i
} }
res1 := mapFunc(mf, 0, 1, 2, 3, 4, 5) res1 := mapFunc(mf, 0, 1, 2, 3, 4, 5)
for _, v := range res1 { for _, v := range res1 {
fmt.Println(v) fmt.Println(v)
} }
println() println()
res2 := mapFunc(mf, "0", "1", "2", "3", "4", "5") res2 := mapFunc(mf, "0", "1", "2", "3", "4", "5")
for _, v := range res2 { for _, v := range res2 {
fmt.Println(v) fmt.Println(v)
} }
} }
func mapFunc(mf func(obj) obj, list ...obj) ([]obj) { func mapFunc(mf func(obj) obj, list ...obj) []obj {
result := make([]obj, len(list)) result := make([]obj, len(list))
for ix, v := range list { for ix, v := range list {
result[ix] = mf(v) result[ix] = mf(v)
} }
// Equivalent: // Equivalent:
/* /*
for ix := 0; ix<len(list); ix++ { for ix := 0; ix<len(list); ix++ {
result[ix] = mf(list[ix]) result[ix] = mf(list[ix])
} }
*/ */
return result return result
} }
/* Output:
0 /* Output:
2 0
4 2
6 4
8 6
10 8
10
00
11 00
22 11
33 22
44 33
55 44
*/ 55
*/

View File

@@ -1,28 +1,30 @@
// min_interface.go // min_interface.go
package min package min
type Miner interface { type Miner interface {
Len() int Len() int
ElemIx(ix int) interface{} ElemIx(ix int) interface{}
Less(i, j int) bool Less(i, j int) bool
} }
func Min(data Miner) interface{} { func Min(data Miner) interface{} {
min := data.ElemIx(0) min := data.ElemIx(0)
for i:=1; i < data.Len(); i++ { for i := 1; i < data.Len(); i++ {
if data.Less(i, i-1) { if data.Less(i, i-1) {
min = data.ElemIx(i) min = data.ElemIx(i)
} }
} }
return min return min
} }
type IntArray []int type IntArray []int
func (p IntArray) Len() int { return len(p) }
func (p IntArray) ElemIx(ix int) interface{} { return p[ix] } func (p IntArray) Len() int { return len(p) }
func (p IntArray) Less(i, j int) bool { return p[i] < p[j] } func (p IntArray) ElemIx(ix int) interface{} { return p[ix] }
func (p IntArray) Less(i, j int) bool { return p[i] < p[j] }
type StringArray []string
func (p StringArray) Len() int { return len(p) } type StringArray []string
func (p StringArray) ElemIx(ix int) interface{} { return p[ix] }
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] } func (p StringArray) Len() int { return len(p) }
func (p StringArray) ElemIx(ix int) interface{} { return p[ix] }
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] }

View File

@@ -1,31 +1,31 @@
// minmain.go // minmain.go
package main package main
import ( import (
"fmt" "./min"
"./min" "fmt"
) )
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 := min.IntArray(data) //conversion to type IntArray a := min.IntArray(data) //conversion to type IntArray
m := min.Min(a) m := min.Min(a)
fmt.Printf("The minimum of the array is: %v\n", m) fmt.Printf("The minimum of the array is: %v\n", m)
} }
func strings() { func strings() {
data := []string{"ddd", "eee", "bbb", "ccc", "aaa"} data := []string{"ddd", "eee", "bbb", "ccc", "aaa"}
a := min.StringArray(data) a := min.StringArray(data)
m := min.Min(a) m := min.Min(a)
fmt.Printf("The minimum of the array is: %v\n", m) fmt.Printf("The minimum of the array is: %v\n", m)
} }
func main() { func main() {
ints() ints()
strings() strings()
} }
/* Output: /* Output:
The minimum of the array is: -5467984 The minimum of the array is: -5467984
The minimum of the array is: aaa The minimum of the array is: aaa
*/ */

View File

@@ -1,89 +1,90 @@
// float64 is necessary as input to math.Sqrt() // float64 is necessary as input to math.Sqrt()
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
) )
type Magnitude interface { type Magnitude interface {
Abs() float64 Abs() float64
} }
var m Magnitude var m Magnitude
type Point struct { type Point struct {
X, Y float64 X, Y float64
} }
func (p *Point) Scale(s float64) { func (p *Point) Scale(s float64) {
p.X *= s p.X *= s
p.Y *= s p.Y *= s
} }
func (p *Point) Abs() float64 { func (p *Point) Abs() float64 {
return math.Sqrt(float64(p.X*p.X + p.Y*p.Y)) return math.Sqrt(float64(p.X*p.X + p.Y*p.Y))
} }
type Point3 struct { type Point3 struct {
X, Y, Z float64 X, Y, Z float64
} }
func (p *Point3) Abs() float64 { func (p *Point3) Abs() float64 {
return math.Sqrt(float64(p.X*p.X + p.Y*p.Y + p.Z*p.Z)) return math.Sqrt(float64(p.X*p.X + p.Y*p.Y + p.Z*p.Z))
} }
type Polar struct { type Polar struct {
R, Theta float64 R, Theta float64
} }
func (p Polar) Abs() float64 { return p.R } func (p Polar) Abs() float64 { return p.R }
func main() { func main() {
p1 := new(Point) p1 := new(Point)
p1.X = 3 p1.X = 3
p1.Y = 4 p1.Y = 4
m = p1 // p1 is type *Point, has method Abs() m = p1 // p1 is type *Point, has method Abs()
fmt.Printf("The length of the vector p1 is: %f\n", m.Abs()) fmt.Printf("The length of the vector p1 is: %f\n", m.Abs())
p2:= &Point{4, 5} p2 := &Point{4, 5}
m = p2 m = p2
fmt.Printf("The length of the vector p2 is: %f\n", m.Abs() ) fmt.Printf("The length of the vector p2 is: %f\n", m.Abs())
p1.Scale(5) p1.Scale(5)
m = p1 m = p1
fmt.Printf("The length of the vector p1 after scaling is: %f\n", m.Abs() ) fmt.Printf("The length of the vector p1 after scaling is: %f\n", m.Abs())
fmt.Printf("Point p1 after scaling has the following coordinates: X %f - Y %f\n", p1.X, p1.Y) fmt.Printf("Point p1 after scaling has the following coordinates: X %f - Y %f\n", p1.X, p1.Y)
mag := m.Abs() mag := m.Abs()
m = &Point3{3, 4, 5} m = &Point3{3, 4, 5}
mag += m.Abs() mag += m.Abs()
m = Polar{2.0, math.Pi / 2} m = Polar{2.0, math.Pi / 2}
mag += m.Abs() mag += m.Abs()
fmt.Printf("The float64 mag is now: %f", mag ) fmt.Printf("The float64 mag is now: %f", mag)
} }
/* Output:
The length of the vector p1 is: 5.000000 /* Output:
The length of the vector p2 is: 6.403124 The length of the vector p1 is: 5.000000
The length of the vector p1 after scaling is: 25.000000 The length of the vector p2 is: 6.403124
Point p1 after scaling has the following coordinates: X 15.000000 - Y 20.000000 The length of the vector p1 after scaling is: 25.000000
The float64 mag is now: 34.071068 Point p1 after scaling has the following coordinates: X 15.000000 - Y 20.000000
The float64 mag is now: 34.071068
-- instead of:
func (p *Point) Abs() float64 { -- instead of:
return math.Sqrt(float64(p.X*p.X + p.Y*p.Y)) func (p *Point) Abs() float64 {
} return math.Sqrt(float64(p.X*p.X + p.Y*p.Y))
m = p1 }
we can write: m = p1
func (p Point) Abs() float64 { we can write:
return math.Sqrt(float64(p.X*p.X + p.Y*p.Y)) func (p Point) Abs() float64 {
} return math.Sqrt(float64(p.X*p.X + p.Y*p.Y))
m = p1 }
and instead of: m = p1
func (p Polar) Abs() float64 { return p.R } and instead of:
m = Polar{2.0, math.Pi / 2} func (p Polar) Abs() float64 { return p.R }
we can write: m = Polar{2.0, math.Pi / 2}
func (p *Polar) Abs() float64 { return p.R } we can write:
m = &Polar{2.0, math.Pi / 2} func (p *Polar) Abs() float64 { return p.R }
with the same output m = &Polar{2.0, math.Pi / 2}
*/ with the same output
*/

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,34 +1,35 @@
// simple_interface.go // simple_interface.go
package main package main
import ( import (
"fmt" "fmt"
) )
type Simpler interface { type Simpler interface {
Get() int Get() int
Put(int) Put(int)
} }
type Simple struct { type Simple struct {
i int i int
} }
func (p *Simple) Get() int { func (p *Simple) Get() int {
return p.i return p.i
} }
func (p *Simple) Put(u int) { func (p *Simple) Put(u int) {
p.i = u p.i = u
} }
func fI(it Simpler) int { func fI(it Simpler) int {
it.Put(5) it.Put(5)
return it.Get() return it.Get()
} }
func main() { func main() {
var s Simple var s Simple
fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer
} }
// Output: 5
// Output: 5

View File

@@ -1,61 +1,62 @@
// simple_interface2.go // simple_interface2.go
package main package main
import ( import (
"fmt" "fmt"
) )
type Simpler interface { type Simpler interface {
Get() int Get() int
Set(int) Set(int)
} }
type Simple struct { type Simple struct {
i int i int
} }
func (p *Simple) Get() int { func (p *Simple) Get() int {
return p.i return p.i
} }
func (p *Simple) Set(u int) { func (p *Simple) Set(u int) {
p.i = u p.i = u
} }
type RSimple struct { type RSimple struct {
i int i int
j int j int
} }
func (p *RSimple) Get() int { func (p *RSimple) Get() int {
return p.j return p.j
} }
func (p *RSimple) Set(u int) { func (p *RSimple) Set(u int) {
p.j = u p.j = u
} }
func fI(it Simpler) int { func fI(it Simpler) int {
switch it.(type) { switch it.(type) {
case *Simple: case *Simple:
it.Set(5) it.Set(5)
return it.Get() return it.Get()
case *RSimple: case *RSimple:
it.Set(50) it.Set(50)
return it.Get() return it.Get()
default: default:
return 99 return 99
} }
return 0 return 0
} }
func main() { func main() {
var s Simple var s Simple
fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer
var r RSimple var r RSimple
fmt.Println(fI(&r)) fmt.Println(fI(&r))
} }
/* Output:
5 /* Output:
50 5
*/ 50
*/

View File

@@ -1,74 +1,75 @@
// simple_interface2.go // simple_interface2.go
package main package main
import ( import (
"fmt" "fmt"
) )
type Simpler interface { type Simpler interface {
Get() int Get() int
Set(int) Set(int)
} }
type Simple struct { type Simple struct {
i int i int
} }
func (p *Simple) Get() int { func (p *Simple) Get() int {
return p.i return p.i
} }
func (p *Simple) Set(u int) { func (p *Simple) Set(u int) {
p.i = u p.i = u
} }
type RSimple struct { type RSimple struct {
i int i int
j int j int
} }
func (p *RSimple) Get() int { func (p *RSimple) Get() int {
return p.j return p.j
} }
func (p *RSimple) Set(u int) { func (p *RSimple) Set(u int) {
p.j = u p.j = u
} }
func fI(it Simpler) int { func fI(it Simpler) int {
switch it.(type) { switch it.(type) {
case *Simple: case *Simple:
it.Set(5) it.Set(5)
return it.Get() return it.Get()
case *RSimple: case *RSimple:
it.Set(50) it.Set(50)
return it.Get() return it.Get()
default: default:
return 99 return 99
} }
return 0 return 0
} }
func gI(any interface{}) int {
func gI(any interface{}) int { // return any.(Simpler).Get() // unsafe, runtime panic possible
// return any.(Simpler).Get() // unsafe, runtime panic possible if v, ok := any.(Simpler); ok {
if v, ok := any.(Simpler); ok { return v.Get()
return v.Get() }
} return 0 // default value
return 0 // default value }
}
/* Output: /* Output:
6 6
60 60
*/ */
func main() { func main() {
var s Simple = Simple{6} var s Simple = Simple{6}
fmt.Println(gI(&s)) // &s is required because Get() is defined with a receiver type pointer fmt.Println(gI(&s)) // &s is required because Get() is defined with a receiver type pointer
var r RSimple = RSimple{60,60} var r RSimple = RSimple{60, 60}
fmt.Println(gI(&r)) fmt.Println(gI(&r))
} }
/* Output:
6 /* Output:
60 6
*/ 60
*/

View File

@@ -1,60 +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.
package sort package sort
type Sorter interface { type Sorter interface {
Len() int Len() int
Less(i, j int) bool Less(i, j int) bool
Swap(i, j int) Swap(i, j int)
} }
/* /*
func Sort(Sorter Interface) { func Sort(Sorter 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)
} }
} }
} }
*/ */
func Sort(data Sorter) { func Sort(data Sorter) {
for pass:=1; pass < data.Len(); pass++ { for pass := 1; pass < data.Len(); pass++ {
for i:=0; i < data.Len() - pass; i++ { for i := 0; i < data.Len()-pass; i++ {
if data.Less(i+1, i) { if data.Less(i+1, i) {
data.Swap(i, i+1) data.Swap(i, i+1)
} }
} }
} }
} }
func IsSorted(data Sorter) bool { func IsSorted(data Sorter) 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 // Convenience types for common cases
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 StringArray []string type StringArray []string
func (p StringArray) Len() int { return len(p) } func (p StringArray) Len() int { return len(p) }
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] } 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) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Convenience wrappers for common cases // Convenience wrappers for common cases
func SortInts(a []int) { Sort(IntArray(a)) } func SortInts(a []int) { Sort(IntArray(a)) }
func SortStrings(a []string) { Sort(StringArray(a)) } func SortStrings(a []string) { Sort(StringArray(a)) }
func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) } func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)) }
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) } func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)) }

View File

@@ -1,36 +1,36 @@
// sort_persons.go // sort_persons.go
package main package main
import ( import (
"fmt" "./sort"
"./sort" "fmt"
) )
type Person struct { type Person struct {
firstName string firstName string
lastName string lastName string
} }
type Persons []Person type Persons []Person
func (p Persons) Len() int { return len(p) } func (p Persons) Len() int { return len(p) }
func (p Persons) Less(i, j int) bool { func (p Persons) Less(i, j int) bool {
in := p[i].lastName + " " + p[i].firstName in := p[i].lastName + " " + p[i].firstName
jn := p[j].lastName + " " + p[j].firstName jn := p[j].lastName + " " + p[j].firstName
return in < jn return in < jn
} }
func (p Persons) Swap(i, j int) { func (p Persons) Swap(i, j int) {
p[i], p[j] = p[j], p[i] p[i], p[j] = p[j], p[i]
} }
func main() { func main() {
p1 := Person{"Xavier","Papadopoulos"} p1 := Person{"Xavier", "Papadopoulos"}
p2 := Person{"Chris","Naegels"} p2 := Person{"Chris", "Naegels"}
p3 := Person{"John","Doe"} p3 := Person{"John", "Doe"}
arrP := Persons{p1,p2,p3} arrP := Persons{p1, p2, p3}
fmt.Printf("Before sorting: %v\n", arrP) fmt.Printf("Before sorting: %v\n", arrP)
sort.Sort(arrP) sort.Sort(arrP)
fmt.Printf("After sorting: %v\n", arrP) fmt.Printf("After sorting: %v\n", arrP)
} }

View File

@@ -1,39 +1,39 @@
// stack.go // stack.go
package stack package stack
import "errors" import "errors"
type Stack []interface{} type Stack []interface{}
func (stack Stack) Len() int { func (stack Stack) Len() int {
return len(stack) return len(stack)
} }
func (stack Stack) Cap() int { func (stack Stack) Cap() int {
return cap(stack) return cap(stack)
} }
func (stack Stack) IsEmpty() bool { func (stack Stack) IsEmpty() bool {
return len(stack) == 0 return len(stack) == 0
} }
func (stack *Stack) Push(e interface{}) { func (stack *Stack) Push(e interface{}) {
*stack = append(*stack, e) *stack = append(*stack, e)
} }
func (stack Stack) Top() (interface{}, error) { func (stack Stack) Top() (interface{}, error) {
if len(stack) == 0 { if len(stack) == 0 {
return nil, errors.New("stack is empty") return nil, errors.New("stack is empty")
} }
return stack[len(stack)-1], nil return stack[len(stack)-1], nil
} }
func (stack *Stack) Pop() (interface{}, error) { func (stack *Stack) Pop() (interface{}, error) {
stk := *stack // dereference to a local variable stk stk := *stack // dereference to a local variable stk
if len(stk) == 0 { if len(stk) == 0 {
return nil, errors.New("stack is empty") return nil, errors.New("stack is empty")
} }
top := stk[len(stk)-1] top := stk[len(stk)-1]
*stack = stk[:len(stk)-1] // shrink the stack *stack = stk[:len(stk)-1] // shrink the stack
return top, nil return top, nil
} }

View File

@@ -1,28 +1,28 @@
// stack_general_v2.go // stack_general_v2.go
// Package collection implements a generic stack. // Package collection implements a generic stack.
package collection package collection
// The zero value for Stack is an empty stack ready to use. // The zero value for Stack is an empty stack ready to use.
type Stack struct { type Stack struct {
data []interface{} data []interface{}
} }
// Push adds x to the top of the stack. // Push adds x to the top of the stack.
func (s *Stack) Push(x interface{}) { func (s *Stack) Push(x interface{}) {
s.data = append(s.data, x) s.data = append(s.data, x)
} }
// Pop removes and returns the top element of the stack. // Pop removes and returns the top element of the stack.
// It's a run-time error to call Pop on an empty stack. // It's a run-time error to call Pop on an empty stack.
func (s *Stack) Pop() interface{} { func (s *Stack) Pop() interface{} {
i := len(s.data) - 1 i := len(s.data) - 1
res := s.data[i] res := s.data[i]
s.data[i] = nil // to avoid memory leak s.data[i] = nil // to avoid memory leak
s.data = s.data[:i] s.data = s.data[:i]
return res return res
} }
// Size returns the number of elements in the stack. // Size returns the number of elements in the stack.
func (s *Stack) Size() int { func (s *Stack) Size() int {
return len(s.data) return len(s.data)
} }

View File

@@ -1,55 +1,55 @@
// calculator.go // calculator.go
// example: calculate 3 + 4 = 7 as input: 3 ENTER 4 ENTER + ENTER --> result = 7, // example: calculate 3 + 4 = 7 as input: 3 ENTER 4 ENTER + ENTER --> result = 7,
package main package main
import ( import (
"fmt" "./stack/stack"
"strconv" "bufio"
"bufio" "fmt"
"os" "os"
"./stack/stack" "strconv"
) )
func main() { func main() {
buf := bufio.NewReader(os.Stdin) buf := bufio.NewReader(os.Stdin)
calc1 := new(stack.Stack) calc1 := new(stack.Stack)
fmt.Println("Give a number, an operator (+, -, *, /), or q to stop:") fmt.Println("Give a number, an operator (+, -, *, /), or q to stop:")
for { for {
token, err := buf.ReadString('\n') token, err := buf.ReadString('\n')
if err != nil { if err != nil {
fmt.Println("Input error !") fmt.Println("Input error !")
os.Exit(1) os.Exit(1)
} }
token = token[0:len(token)-2] // remove "\r\n" token = token[0 : len(token)-2] // remove "\r\n"
// fmt.Printf("--%s--\n",token) // debug statement // fmt.Printf("--%s--\n",token) // debug statement
switch { switch {
case token == "q": // stop als invoer = "q" case token == "q": // stop als invoer = "q"
fmt.Println("Calculator stopped") fmt.Println("Calculator stopped")
return return
case token >= "0" && token <= "999999": case token >= "0" && token <= "999999":
i, _ := strconv.Atoi(token) i, _ := strconv.Atoi(token)
calc1.Push(i) calc1.Push(i)
case token == "+": case token == "+":
q, _ := calc1.Pop() q, _ := calc1.Pop()
p, _ := calc1.Pop() p, _ := calc1.Pop()
fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int) + q.(int)) fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int)+q.(int))
case token == "-": case token == "-":
q, _ := calc1.Pop() q, _ := calc1.Pop()
p, _ := calc1.Pop() p, _ := calc1.Pop()
fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int) - q.(int)) fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int)-q.(int))
case token == "*": case token == "*":
q, _ := calc1.Pop() q, _ := calc1.Pop()
p, _ := calc1.Pop() p, _ := calc1.Pop()
fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int) * q.(int)) fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int)*q.(int))
case token == "/": case token == "/":
q, _ := calc1.Pop() q, _ := calc1.Pop()
p, _ := calc1.Pop() p, _ := calc1.Pop()
fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int) / q.(int)) fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p.(int)/q.(int))
default: default:
fmt.Println("No valid input") fmt.Println("No valid input")
} }
} }
} }

View File

@@ -1,43 +1,43 @@
package main package main
import ( import (
"os" "bufio"
"io" "flag"
"fmt" "fmt"
"bufio" "io"
"flag" "os"
) )
var numberFlag = flag.Bool("n", false, "number each line") var numberFlag = flag.Bool("n", false, "number each line")
func cat(r *bufio.Reader) { func cat(r *bufio.Reader) {
i := 1 i := 1
for { for {
buf, err := r.ReadBytes('\n') buf, err := r.ReadBytes('\n')
if err == io.EOF { if err == io.EOF {
break break
} }
if *numberFlag { if *numberFlag {
fmt.Fprintf(os.Stdout, "%5d %s", i, buf) fmt.Fprintf(os.Stdout, "%5d %s", i, buf)
i++ i++
} else { } else {
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,42 @@
// degob.go // degob.go
package main package main
import ( import (
"bufio" "bufio"
"fmt" "encoding/gob"
"encoding/gob" "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
} }
var content string var content string
var vc VCard var vc VCard
func main() { func main() {
// using a decoder: // using a decoder:
file, _ := os.Open("vcard.gob") file, _ := os.Open("vcard.gob")
defer file.Close() defer file.Close()
inReader := bufio.NewReader(file) inReader := bufio.NewReader(file)
dec := gob.NewDecoder(inReader) dec := gob.NewDecoder(inReader)
err := dec.Decode(&vc) err := dec.Decode(&vc)
if err != nil { if err != nil {
log.Println("Error in decoding gob") log.Println("Error in decoding gob")
} }
fmt.Println(vc) fmt.Println(vc)
} }
// Output:
// {Jan Kersschot [0x12642e60 0x12642e80] none} // Output:
// {Jan Kersschot [0x12642e60 0x12642e80] none}

View File

@@ -1,20 +1,21 @@
// hash_md5.go // hash_md5.go
package main package main
import ( import (
"fmt"; "crypto/md5"
"crypto/md5" "fmt"
"io" "io"
) )
func main() { func main() {
hasher := md5.New() hasher := md5.New()
b := []byte{} b := []byte{}
io.WriteString(hasher, "test") io.WriteString(hasher, "test")
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))
} }
/* Output:
Result: 098f6bcd4621d373cade4e832627b4f6 /* Output:
Result: [9 143 107 205 70 33 211 115 202 222 78 131 38 39 180 246] Result: 098f6bcd4621d373cade4e832627b4f6
*/ Result: [9 143 107 205 70 33 211 115 202 222 78 131 38 39 180 246]
*/

View File

@@ -1,16 +1,16 @@
// hello_who.go // hello_who.go
package main package main
import ( import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
) )
func main() { func main() {
who := "World" who := "World"
if len(os.Args) > 1 { // os.Args[0] == hello_who if len(os.Args) > 1 { // os.Args[0] == hello_who
who = strings.Join(os.Args[1:], " ") who = strings.Join(os.Args[1:], " ")
} }
fmt.Println("Hello", who, "!") fmt.Println("Hello", who, "!")
} }

View File

@@ -1,67 +1,68 @@
// read_csv.go // read_csv.go
package main package main
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"log" "io"
"io" "log"
"os" "os"
"strconv" "strconv"
"strings" "strings"
) )
type Book struct { type Book struct {
title string title string
price float64 price float64
quantity int quantity int
} }
func main() { func main() {
bks := make([]Book, 1) bks := make([]Book, 1)
file, err := os.Open("products.txt") file, err := os.Open("products.txt")
if err != nil { if err != nil {
log.Fatalf("Error %s opening file products.txt: ", err) log.Fatalf("Error %s opening file products.txt: ", err)
} }
defer file.Close() defer file.Close()
reader := bufio.NewReader(file) reader := bufio.NewReader(file)
for { for {
// read one line from the file: // read one line from the file:
line, err := reader.ReadString('\n') line, err := reader.ReadString('\n')
if err == io.EOF { if err == io.EOF {
break break
} }
// remove \r and \n so 2(in Windows, in Linux only \n, so 1): // remove \r and \n so 2(in Windows, in Linux only \n, so 1):
line = string(line[:len(line)-2]) line = string(line[:len(line)-2])
//fmt.Printf("The input was: -%s-", line) //fmt.Printf("The input was: -%s-", line)
strSl := strings.Split(line, ";") strSl := strings.Split(line, ";")
book := new(Book) book := new(Book)
book.title = strSl[0] book.title = strSl[0]
book.price, err = strconv.ParseFloat(strSl[1], 32) book.price, err = strconv.ParseFloat(strSl[1], 32)
if err!=nil { if err != nil {
fmt.Printf("Error in file: %v", err) fmt.Printf("Error in file: %v", err)
} }
//fmt.Printf("The quan was:-%s-", strSl[2]) //fmt.Printf("The quan was:-%s-", strSl[2])
book.quantity, err = strconv.Atoi(strSl[2]) book.quantity, err = strconv.Atoi(strSl[2])
if err!=nil { if err != nil {
fmt.Printf("Error in file: %v", err) fmt.Printf("Error in file: %v", err)
} }
if bks[0].title == "" { if bks[0].title == "" {
bks[0] = *book bks[0] = *book
} else { } else {
bks = append(bks, *book) bks = append(bks, *book)
} }
} }
fmt.Println("We have read the following books from the file: ") fmt.Println("We have read the following books from the file: ")
for _, bk := range bks { for _, bk := range bks {
fmt.Println(bk) fmt.Println(bk)
} }
} }
/* Output:
We have read the following books from the file: /* Output:
{"The ABC of Go" 25.5 1500} We have read the following books from the file:
{"Functional Programming with Go" 56 280} {"The ABC of Go" 25.5 1500}
{"Go for It" 45.900001525878906 356} {"Functional Programming with Go" 56 280}
*/ {"Go for It" 45.900001525878906 356}
*/

View File

@@ -1,37 +1,37 @@
// remove_first6char.go // remove_first6char.go
package main package main
import ( import (
"fmt" "bufio"
"io" "fmt"
"bufio" "io"
"os" "os"
) )
func main() { func main() {
inputFile, _ := os.Open("goprogram") inputFile, _ := os.Open("goprogram")
outputFile, _ := os.OpenFile("goprogramT", os.O_WRONLY|os.O_CREATE, 0666) outputFile, _ := os.OpenFile("goprogramT", os.O_WRONLY|os.O_CREATE, 0666)
defer inputFile.Close() defer inputFile.Close()
defer outputFile.Close() defer outputFile.Close()
inputReader := bufio.NewReader(inputFile) inputReader := bufio.NewReader(inputFile)
outputWriter := bufio.NewWriter(outputFile) outputWriter := bufio.NewWriter(outputFile)
for { for {
// inputString, readerError := inputReader.ReadString('\n') // inputString, readerError := inputReader.ReadString('\n')
inputString, _, readerError := inputReader.ReadLine() inputString, _, readerError := inputReader.ReadLine()
if readerError == io.EOF { if readerError == io.EOF {
fmt.Println("EOF") fmt.Println("EOF")
break break
} }
//fmt.Printf("The input was: --%s--", inputString) //fmt.Printf("The input was: --%s--", inputString)
outputString := string([]byte(inputString)[2:5]) + "\r\n" outputString := string([]byte(inputString)[2:5]) + "\r\n"
//fmt.Printf("The output was: --%s--", outputString) //fmt.Printf("The output was: --%s--", outputString)
_, err := outputWriter.WriteString(outputString) _, err := outputWriter.WriteString(outputString)
//fmt.Printf("Number of bytes written %d\n", n) //fmt.Printf("Number of bytes written %d\n", n)
if (err != nil) { if err != nil {
fmt.Println(err) fmt.Println(err)
return return
} }
} }
outputWriter.Flush() outputWriter.Flush()
fmt.Println("Conversion done") fmt.Println("Conversion done")
} }

View File

@@ -1,32 +1,32 @@
// stack_struct.go // stack_struct.go
package stack package stack
import "strconv" import "strconv"
const LIMIT = 10
const LIMIT = 10
type Stack struct {
ix int // first free position, so data[ix] == 0 type Stack struct {
data [LIMIT]int ix int // first free position, so data[ix] == 0
} data [LIMIT]int
}
func (st *Stack) Push(n int) {
if (st.ix + 1 > LIMIT) { func (st *Stack) Push(n int) {
return // stack is full! if st.ix+1 > LIMIT {
} return // stack is full!
st.data[st.ix] = n }
st.ix++ st.data[st.ix] = n
} st.ix++
}
func (st *Stack) Pop() int {
st.ix-- func (st *Stack) Pop() int {
return st.data[st.ix] st.ix--
} return st.data[st.ix]
}
func (st Stack) String() string {
str := "" func (st Stack) String() string {
for ix:=0; ix<st.ix; ix++ { str := ""
str += "[" + strconv.Itoa(ix) + ":" + strconv.Itoa(st.data[ix]) + "] " for ix := 0; ix < st.ix; ix++ {
} str += "[" + strconv.Itoa(ix) + ":" + strconv.Itoa(st.data[ix]) + "] "
return str }
} return str
}

View File

@@ -33,6 +33,7 @@ func main() {
new_page.load("Page.md") new_page.load("Page.md")
fmt.Println(string(new_page.Body)) fmt.Println(string(new_page.Body))
} }
/* Output: /* Output:
* # Page * # Page
* ## Section1 * ## Section1

View File

@@ -1,36 +1,37 @@
// Q28_word_letter_count.go // Q28_word_letter_count.go
package main package main
import ( import (
"fmt" "bufio"
"bufio" "fmt"
"os" "os"
"strings" "strings"
) )
var nrchars, nrwords, nrlines int
var nrchars, nrwords, nrlines int
func main() {
nrchars, nrwords, nrlines = 0, 0, 0 func main() {
inputReader := bufio.NewReader(os.Stdin) nrchars, nrwords, nrlines = 0, 0, 0
fmt.Println("Please enter some input, type S to stop: ") inputReader := bufio.NewReader(os.Stdin)
for { fmt.Println("Please enter some input, type S to stop: ")
input, err := inputReader.ReadString('\n') for {
if err != nil { input, err := inputReader.ReadString('\n')
fmt.Printf("An error occurred: %s\n", err) if err != nil {
} fmt.Printf("An error occurred: %s\n", err)
if input == "S\r\n" { // Windows, on Linux it is "S\n" }
fmt.Println("Here are the counts:") if input == "S\r\n" { // Windows, on Linux it is "S\n"
fmt.Printf("Number of characters: %d\n", nrchars) fmt.Println("Here are the counts:")
fmt.Printf("Number of words: %d\n", nrwords) fmt.Printf("Number of characters: %d\n", nrchars)
fmt.Printf("Number of lines: %d\n", nrlines) fmt.Printf("Number of words: %d\n", nrwords)
os.Exit(0) fmt.Printf("Number of lines: %d\n", nrlines)
} os.Exit(0)
Counters(input) }
} Counters(input)
} }
}
func Counters(input string) {
nrchars += len(input) - 2 // -2 for \r\n func Counters(input string) {
nrwords += len(strings.Fields(input)) nrchars += len(input) - 2 // -2 for \r\n
nrlines++ nrwords += len(strings.Fields(input))
} nrlines++
}

View File

@@ -1,44 +1,45 @@
// panic_defer.go // panic_defer.go
package main package main
import "fmt" import "fmt"
func main() { func main() {
f() f()
fmt.Println("Returned normally from f.") fmt.Println("Returned normally from f.")
} }
func f() { func f() {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
fmt.Println("Recovered in f", r) fmt.Println("Recovered in f", r)
} }
}() }()
fmt.Println("Calling g.") fmt.Println("Calling g.")
g(0) g(0)
fmt.Println("Returned normally from g.") fmt.Println("Returned normally from g.")
} }
func g(i int) { func g(i int) {
if i > 3 { if i > 3 {
fmt.Println("Panicking!") fmt.Println("Panicking!")
panic(fmt.Sprintf("%v", i)) panic(fmt.Sprintf("%v", i))
} }
defer fmt.Println("Defer in g", i) defer fmt.Println("Defer in g", i)
fmt.Println("Printing in g", i) fmt.Println("Printing in g", i)
g(i + 1) g(i + 1)
} }
/* Output:
Calling g. /* Output:
Printing in g 0 Calling g.
Printing in g 1 Printing in g 0
Printing in g 2 Printing in g 1
Printing in g 3 Printing in g 2
Panicking! Printing in g 3
Defer in g 3 Panicking!
Defer in g 2 Defer in g 3
Defer in g 1 Defer in g 2
Defer in g 0 Defer in g 1
Recovered in f 4 Defer in g 0
Returned normally from f. Recovered in f 4
*/ Returned normally from f.
*/

View File

@@ -1,44 +1,45 @@
// panic_defer_convint.go // panic_defer_convint.go
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
) )
func main() { func main() {
l := int64(15000) l := int64(15000)
if i, err := IntFromInt64(l); err!= nil { if i, err := IntFromInt64(l); err != nil {
fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error()) fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error())
} else { } else {
fmt.Printf("%d converted to an int32 is %d", l, i) fmt.Printf("%d converted to an int32 is %d", l, i)
} }
fmt.Println() fmt.Println()
l = int64(math.MaxInt32 + 15000) l = int64(math.MaxInt32 + 15000)
if i, err := IntFromInt64(l); err!= nil { if i, err := IntFromInt64(l); err != nil {
fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error()) fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error())
} else { } else {
fmt.Printf("%d converted to an int32 is %d", l, i) fmt.Printf("%d converted to an int32 is %d", l, i)
} }
} }
func ConvertInt64ToInt(l int64) int { func ConvertInt64ToInt(l int64) int {
if math.MinInt32 <= l && l <= math.MaxInt32 { if math.MinInt32 <= l && l <= math.MaxInt32 {
return int(l) return int(l)
} }
panic(fmt.Sprintf("%d is out of the int32 range", l)) panic(fmt.Sprintf("%d is out of the int32 range", l))
} }
func IntFromInt64(l int64) (i int, err error) { func IntFromInt64(l int64) (i int, err error) {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
err = fmt.Errorf("%v", e) err = fmt.Errorf("%v", e)
} }
}() }()
i = ConvertInt64ToInt(l) i = ConvertInt64ToInt(l)
return i, nil return i, nil
} }
/* Output:
15000 converted to an int32 is 15000 /* Output:
The conversion of 2147498647 to an int32 resulted in an error: 2147498647 is out of the int32 range 15000 converted to an int32 is 15000
*/ The conversion of 2147498647 to an int32 resulted in an error: 2147498647 is out of the int32 range
*/

View File

@@ -1,34 +1,35 @@
// recover_divbyzero.go // recover_divbyzero.go
package main package main
import ( import (
"fmt" "fmt"
) )
func badCall() { func badCall() {
a, b := 10, 0 a, b := 10, 0
n := a / b n := a / b
fmt.Println(n) fmt.Println(n)
} }
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"); fmt.Printf("After bad call\r\n")
} }
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:
Calling test /* Output:
Panicing runtime error: integer divide by zero Calling test
Test completed Panicing runtime error: integer divide by zero
*/ Test completed
*/

View File

@@ -1,18 +1,18 @@
// string_reverse.go // string_reverse.go
package strev package strev
func Reverse(s string) string { func Reverse(s string) string {
runes := []rune(s) runes := []rune(s)
n, h := len(runes), len(runes)/2 n, h := len(runes), len(runes)/2
for i := 0; i < h; i++ { for i := 0; i < h; i++ {
runes[i], runes[n-1-i] = runes[n-1-i], runes[i] runes[i], runes[n-1-i] = runes[n-1-i], runes[i]
} }
return string(runes) return string(runes)
} }
/* /*
func main() { func main() {
s := "My Test String!" s := "My Test String!"
fmt.Println(s, " --> ", Reverse(s)) fmt.Println(s, " --> ", Reverse(s))
} }
*/ */

View File

@@ -1,40 +1,40 @@
// string_reverse_test.go // string_reverse_test.go
package strev package strev
import "testing" import "testing"
import "./strev" import "./strev"
type ReverseTest struct { type ReverseTest struct {
in, out string in, out string
} }
var ReverseTests = []ReverseTest { var ReverseTests = []ReverseTest{
ReverseTest{"ABCD", "DCBA"}, {"ABCD", "DCBA"},
ReverseTest{"CVO-AZ", "ZA-OVC"}, {"CVO-AZ", "ZA-OVC"},
ReverseTest{"Hello 世界", "界世 olleH"}, {"Hello 世界", "界世 olleH"},
} }
func TestReverse(t *testing.T) { func TestReverse(t *testing.T) {
/* /*
in := "CVO-AZ" in := "CVO-AZ"
out := Reverse(in) out := Reverse(in)
exp := "ZA-OVC" exp := "ZA-OVC"
if out != exp { if out != exp {
t.Errorf("Reverse of %s expects %s, but got %s", in, exp, out) t.Errorf("Reverse of %s expects %s, but got %s", in, exp, out)
} }
*/ */
// testing with a battery of testdata: // testing with a battery of testdata:
for _, r := range ReverseTests { for _, r := range ReverseTests {
exp := strev.Reverse(r.in) exp := strev.Reverse(r.in)
if r.out != exp { if r.out != exp {
t.Errorf("Reverse of %s expects %s, but got %s", r.in, exp, r.out) t.Errorf("Reverse of %s expects %s, but got %s", r.in, exp, r.out)
} }
} }
} }
func BenchmarkReverse(b *testing.B) { func BenchmarkReverse(b *testing.B) {
s := "ABCD" s := "ABCD"
for i:=0; i < b.N; i++ { for i := 0; i < b.N; i++ {
strev.Reverse(s) strev.Reverse(s)
} }
} }

View File

@@ -1,19 +1,19 @@
// blocking.go // blocking.go
// throw: all goroutines are asleep - deadlock! // throw: all goroutines are asleep - deadlock!
package main package main
import ( import (
"fmt" "fmt"
) )
func f1(in chan int) { func f1(in chan int) {
fmt.Println(<-in) fmt.Println(<-in)
} }
func main() { func main() {
out := make(chan int) out := make(chan int)
//out := make(chan int, 1) // solution 2 //out := make(chan int, 1) // solution 2
// go f1(out) // solution 1 // go f1(out) // solution 1
out <- 2 out <- 2
go f1(out) go f1(out)
} }

View File

@@ -1,22 +1,23 @@
package main package main
import "fmt" import "fmt"
import "time" import "time"
func main() { func main() {
c := make(chan int) c := make(chan int)
go func() { go func() {
time.Sleep(15 * 1e9) time.Sleep(15 * 1e9)
x := <-c x := <-c
fmt.Println("received", x) fmt.Println("received", x)
}() }()
fmt.Println("sending", 10) fmt.Println("sending", 10)
c <- 10 c <- 10
fmt.Println("sent", 10) fmt.Println("sent", 10)
} }
/* Output:
sending 10 /* Output:
(15 s later): sending 10
received 10 (15 s later):
sent 10 received 10
*/ sent 10
*/

View File

@@ -1,21 +1,22 @@
package main package main
import "fmt" import "fmt"
import "time" import "time"
func main() { func main() {
c := make(chan int, 50) c := make(chan int, 50)
go func() { go func() {
time.Sleep(15 * 1e9) time.Sleep(15 * 1e9)
x := <-c x := <-c
fmt.Println("received", x) fmt.Println("received", x)
}() }()
fmt.Println("sending", 10) fmt.Println("sending", 10)
c <- 10 c <- 10
fmt.Println("sent", 10) fmt.Println("sent", 10)
} }
/* Output:
sending 10 /* Output:
sent 10 // prints immediately sending 10
no further output, because main() then stops sent 10 // prints immediately
*/ no further output, because main() then stops
*/

View File

@@ -1,45 +1,46 @@
// Concurrent computation of pi. // Concurrent computation of pi.
// See http://goo.gl/ZuTZM. - Comparison with Scala! // See http://goo.gl/ZuTZM. - Comparison with Scala!
// //
// This demonstrates Go's ability to handle // This demonstrates Go's ability to handle
// large numbers of concurrent processes. // large numbers of concurrent processes.
// It is an unreasonable way to calculate pi. // It is an unreasonable way to calculate pi.
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
"time" "time"
) )
func main() { func main() {
start := time.Now() start := time.Now()
fmt.Println(CalculatePi(5000)) fmt.Println(CalculatePi(5000))
end := time.Now() end := time.Now()
delta := end.Sub(start) delta := end.Sub(start)
fmt.Printf("longCalculation took this amount of time: %s\n", delta) fmt.Printf("longCalculation took this amount of time: %s\n", delta)
} }
// CalculatePi launches n goroutines to compute an // CalculatePi launches n goroutines to compute an
// series-approximation of pi. // series-approximation of pi.
func CalculatePi(n int) float64 { func CalculatePi(n int) float64 {
ch := make(chan float64) ch := make(chan float64)
for k := 0; k <= n; k++ { for k := 0; k <= n; k++ {
// calculate k-th term in the series // calculate k-th term in the series
go term(ch, float64(k)) go term(ch, float64(k))
} }
f := 0.0 f := 0.0
//wait for all goroutines to complete, get and sum up their results: //wait for all goroutines to complete, get and sum up their results:
for k := 0; k <= n; k++ { for k := 0; k <= n; k++ {
f += <-ch f += <-ch
} }
return f return f
} }
func term(ch chan float64, k float64) { func term(ch chan float64, k float64) {
ch <- 4 * math.Pow(-1, k) / (2*k + 1) ch <- 4 * math.Pow(-1, k) / (2*k + 1)
} }
/* Output:
3.14179261359579 /* Output:
The calculation took this amount of time: 0.028002 3.14179261359579
*/ The calculation took this amount of time: 0.028002
*/

View File

@@ -1,45 +1,46 @@
// concurrent_pi2.go // concurrent_pi2.go
package main package main
import ( import (
"fmt" "fmt"
"math" "math"
"runtime" "runtime"
"time" "time"
) )
const NCPU = 2 const NCPU = 2
func main() { func main() {
start := time.Now() start := time.Now()
runtime.GOMAXPROCS(2) runtime.GOMAXPROCS(2)
fmt.Println(CalculatePi(5000)) fmt.Println(CalculatePi(5000))
end := time.Now() end := time.Now()
delta := end.Sub(start) delta := end.Sub(start)
fmt.Printf("longCalculation took this amount of time: %s\n", delta) fmt.Printf("longCalculation took this amount of time: %s\n", delta)
} }
func CalculatePi(end int) float64 { func CalculatePi(end int) float64 {
ch := make(chan float64) ch := make(chan float64)
for i := 0; i < NCPU; i++ { for i := 0; i < NCPU; i++ {
go term(ch, i*end/NCPU, (i+1)*end/NCPU) go term(ch, i*end/NCPU, (i+1)*end/NCPU)
} }
result := 0.0 result := 0.0
for i := 0; i < NCPU; i++ { for i := 0; i < NCPU; i++ {
result += <-ch result += <-ch
} }
return result return result
} }
func term(ch chan float64, start, end int) { func term(ch chan float64, start, end int) {
result := 0.0 result := 0.0
for i := start; i < end; i++ { for i := start; i < end; i++ {
x := float64(i) x := float64(i)
result += 4 * (math.Pow(-1, x) / (2.0*x + 1.0)) result += 4 * (math.Pow(-1, x) / (2.0*x + 1.0))
} }
ch <- result ch <- result
} }
/* Output:
3.1413926535917938 /* Output:
The calculation took this amount of time: 0.002000 3.1413926535917938
*/ The calculation took this amount of time: 0.002000
*/

View File

@@ -1,59 +1,60 @@
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() {
fibFunc := func(state Any) (Any, Any) { fibFunc := func(state Any) (Any, Any) {
os := state.([]uint64) os := state.([]uint64)
v1 := os[0] v1 := os[0]
v2 := os[1] v2 := os[1]
ns := []uint64{v2, v1 + v2} ns := []uint64{v2, v1 + v2}
return v1, ns return v1, ns
} }
fib := BuildLazyUInt64Evaluator(fibFunc, []uint64{0, 1}) fib := BuildLazyUInt64Evaluator(fibFunc, []uint64{0, 1})
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
fmt.Printf("Fib nr %v: %v\n", i, fib()) fmt.Printf("Fib nr %v: %v\n", i, fib())
} }
} }
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 BuildLazyUInt64Evaluator(evalFunc EvalFunc, initState Any) func() uint64 { func BuildLazyUInt64Evaluator(evalFunc EvalFunc, initState Any) func() uint64 {
ef := BuildLazyEvaluator(evalFunc, initState) ef := BuildLazyEvaluator(evalFunc, initState)
return func() uint64 { return func() uint64 {
return ef().(uint64) return ef().(uint64)
} }
} }
/* Output:
Fib nr 0: 0 /* Output:
Fib nr 1: 1 Fib nr 0: 0
Fib nr 2: 1 Fib nr 1: 1
Fib nr 3: 2 Fib nr 2: 1
Fib nr 4: 3 Fib nr 3: 2
Fib nr 5: 5 Fib nr 4: 3
Fib nr 6: 8 Fib nr 5: 5
Fib nr 7: 13 Fib nr 6: 8
Fib nr 8: 21 Fib nr 7: 13
Fib nr 9: 34 Fib nr 8: 21
*/ Fib nr 9: 34
*/

View File

@@ -1,44 +1,44 @@
// Q26_fibonacci_go.go // Q26_fibonacci_go.go
package main package main
import ( import (
"fmt" "fmt"
"time" "os"
"os" "time"
) )
func main() { func main() {
term := 25 term := 25
i := 0 i := 0
c := make(chan int) c := make(chan int)
start := time.Now() start := time.Now()
go fibnterms(term, c) go fibnterms(term, c)
for { for {
if result, ok := <-c; ok { if result, ok := <-c; ok {
fmt.Printf("fibonacci(%d) is: %d\n", i, result) fmt.Printf("fibonacci(%d) is: %d\n", i, result)
i++ i++
} else { } else {
end := time.Now() end := time.Now()
delta := end.Sub(start) delta := end.Sub(start)
fmt.Printf("longCalculation took this amount of time: %s\n", delta) fmt.Printf("longCalculation took this amount of time: %s\n", delta)
os.Exit(0) os.Exit(0)
} }
} }
} }
func fibnterms(term int, c chan int) { func fibnterms(term int, c chan int) {
for i := 0; i <= term; i++ { for i := 0; i <= term; i++ {
c <- fibonacci(i) c <- fibonacci(i)
} }
close(c) close(c)
} }
func fibonacci(n int) (res int) { func fibonacci(n int) (res int) {
if n <= 1 { if n <= 1 {
res = 1 res = 1
} else { } else {
res = fibonacci(n-1) + fibonacci(n-2) res = fibonacci(n-1) + fibonacci(n-2)
} }
return return
} }

View File

@@ -1,35 +1,36 @@
// gofibonacci2.go // gofibonacci2.go
package main package main
import ( import (
"fmt" "fmt"
) )
func fibonacci(n int, c chan int) { func fibonacci(n int, c chan int) {
x, y := 1, 1 x, y := 1, 1
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
c <- x c <- x
x, y = y, x+y x, y = y, x+y
} }
close(c) close(c)
} }
func main() { func main() {
c := make(chan int, 10) c := make(chan int, 10)
go fibonacci(cap(c), c) go fibonacci(cap(c), c)
for i := range c { for i := range c {
fmt.Println(i) fmt.Println(i)
} }
} }
/* Output:
1 /* Output:
1 1
2 1
3 2
5 3
8 5
13 8
21 13
34 21
55 34
*/ 55
*/

View File

@@ -1,45 +1,45 @@
// courtesy of: http://sdh33b.blogspot.com/2009/12/fibonacci-in-go.html // courtesy of: http://sdh33b.blogspot.com/2009/12/fibonacci-in-go.html
package main package main
import ( import (
"fmt" "fmt"
"time" "time"
) )
func dup3(in <-chan int) (<-chan int, <-chan int, <-chan int) { func dup3(in <-chan int) (<-chan int, <-chan int, <-chan int) {
a, b, c := make(chan int, 2), make(chan int, 2), make(chan int, 2) a, b, c := make(chan int, 2), make(chan int, 2), make(chan int, 2)
go func() { go func() {
for { for {
x := <-in x := <-in
a <- x a <- x
b <- x b <- x
c <- x c <- x
} }
}() }()
return a, b, c return a, b, c
} }
func fib() <-chan int { func fib() <-chan int {
x := make(chan int, 2) x := make(chan int, 2)
a, b, out := dup3(x) a, b, out := dup3(x)
go func() { go func() {
x <- 0 x <- 0
x <- 1 x <- 1
<-a <-a
for { for {
x <- <-a + <-b x <- <-a + <-b
} }
}() }()
return out return out
} }
func main() { func main() {
start := time.Now() start := time.Now()
x := fib() x := fib()
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
fmt.Println(<-x) fmt.Println(<-x)
} }
end := time.Now() end := time.Now()
delta := end.Sub(start) delta := end.Sub(start)
fmt.Printf("longCalculation took this amount of time: %s\n", delta) fmt.Printf("longCalculation took this amount of time: %s\n", delta)
} }

View File

@@ -1,42 +1,43 @@
// gofibonacci_select.go // gofibonacci_select.go
package main package main
import "fmt" import "fmt"
func fibonacci(c, quit chan int) { func fibonacci(c, quit chan int) {
x, y := 1, 1 x, y := 1, 1
for { for {
select { select {
case c <- x: case c <- x:
x, y = y, x+y x, y = y, x+y
case <-quit: case <-quit:
fmt.Println("quit") fmt.Println("quit")
return return
} }
} }
} }
func main() { func main() {
c := make(chan int) c := make(chan int)
quit := make(chan int) quit := make(chan int)
go func() { go func() {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
fmt.Println(<-c) fmt.Println(<-c)
} }
quit <- 0 quit <- 0
}() }()
fibonacci(c, quit) fibonacci(c, quit)
} }
/* Output:
1 /* Output:
1 1
2 1
3 2
5 3
8 5
13 8
21 13
34 21
55 34
quit 55
*/ quit
*/

View File

@@ -1,26 +1,26 @@
// Q20_goroutine.go // Q20_goroutine.go
package main package main
import ( import (
"fmt" "fmt"
) )
func tel(ch chan int) { func tel(ch chan int) {
for i:=0; i < 15; i++ { for i := 0; i < 15; i++ {
ch <- i ch <- i
} }
close(ch) // if this is ommitted: panic: all goroutines are asleep - deadlock! close(ch) // if this is ommitted: panic: all goroutines are asleep - deadlock!
} }
func main() { func main() {
var ok = true var ok = true
var i int var i int
ch := make(chan int) ch := make(chan int)
go tel(ch) go tel(ch)
for ok { for ok {
if i, ok= <-ch; ok { if i, ok = <-ch; ok {
fmt.Printf("ok is %t and the counter is at %d\n", ok, i) fmt.Printf("ok is %t and the counter is at %d\n", ok, i)
} }
} }
} }

View File

@@ -1,22 +1,22 @@
package main package main
import ( import (
"fmt" "fmt"
) )
func tel(ch chan int) { func tel(ch chan int) {
for i := 0; i < 15; i++ { for i := 0; i < 15; i++ {
ch <- i ch <- i
} }
} }
func main() { func main() {
var ok = true var ok = true
ch := make(chan int) ch := make(chan int)
go tel(ch) go tel(ch)
for ok { for ok {
i := <-ch i := <-ch
fmt.Printf("ok is %t and the counter is at %d\n", ok, i) fmt.Printf("ok is %t and the counter is at %d\n", ok, i)
} }
} }

View File

@@ -1,31 +1,30 @@
// Q20b_goroutine.go // Q20b_goroutine.go
package main package main
import ( import (
"fmt" "fmt"
"os" "os"
) )
func tel(ch chan int, quit chan bool) { func tel(ch chan int, quit chan bool) {
for i:=0; i < 15; i++ { for i := 0; i < 15; i++ {
ch <- i ch <- i
} }
quit <- true quit <- true
} }
func main() { func main() {
var ok = true var ok = true
ch := make(chan int) ch := make(chan int)
quit := make(chan bool) quit := make(chan bool)
go tel(ch, quit) go tel(ch, quit)
for ok { for ok {
select { select {
case i:= <-ch: case i := <-ch:
fmt.Printf("The counter is at %d\n", i) fmt.Printf("The counter is at %d\n", i)
case <-quit: case <-quit:
os.Exit(0) os.Exit(0)
} }
} }
} }

View File

@@ -1,16 +1,16 @@
// gosum.go // gosum.go
package main package main
import ( import (
"fmt" "fmt"
) )
func sum(x, y int, c chan int) { func sum(x, y int, c chan int) {
c <- x + y c <- x + y
} }
func main() { func main() {
c := make(chan int) c := make(chan int)
go sum(12, 13, c) go sum(12, 13, c)
fmt.Println(<-c) // 25 fmt.Println(<-c) // 25
} }

View File

@@ -1,58 +1,59 @@
// 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 (r *Request) String() string { func (r *Request) String() string {
return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc) return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc)
} }
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 // stop infinite loop return // stop infinite loop
} }
} }
} }
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 })
// make requests: // make requests:
req1 := &Request{3, 4, make(chan int)} req1 := &Request{3, 4, make(chan int)}
req2 := &Request{150, 250, make(chan int)} req2 := &Request{150, 250, make(chan int)}
// send requests on the service channel // send requests on the service channel
adder <- req1 adder <- req1
adder <- req2 adder <- req2
// ask for the results: ( method String() is called ) // ask for the results: ( method String() is called )
fmt.Println(req1, req2) fmt.Println(req1, req2)
// shutdown server: // shutdown server:
quit <- true quit <- true
fmt.Print("done") fmt.Print("done")
} }
/* output:
3+4=7 150+250=400 /* output:
done 3+4=7 150+250=400
*/ done
*/

View File

@@ -1,101 +1,102 @@
// polartocartesian.go // polartocartesian.go
package main package main
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"math" "math"
"os" "os"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
) )
type polar struct { type polar struct {
radius float64 radius float64
Θ float64 Θ float64
} }
type cartesian struct { type cartesian struct {
x float64 x float64
y float64 y float64
} }
const result = "Polar: radius=%.02f angle=%.02f degrees -- Cartesian: x=%.02f y=%.02f\n" const result = "Polar: radius=%.02f angle=%.02f degrees -- Cartesian: x=%.02f y=%.02f\n"
var prompt = "Enter a radius and an angle (in degrees), e.g., 12.5 90, " + "or %s to quit." var prompt = "Enter a radius and an angle (in degrees), e.g., 12.5 90, " + "or %s to quit."
func init() { func init() {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter") prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter")
} else { // Unix-like } else { // Unix-like
prompt = fmt.Sprintf(prompt, "Ctrl+D") prompt = fmt.Sprintf(prompt, "Ctrl+D")
} }
} }
func main() { func main() {
questions := make(chan polar) questions := make(chan polar)
defer close(questions) defer close(questions)
answers := createSolver(questions) answers := createSolver(questions)
defer close(answers) defer close(answers)
interact(questions, answers) interact(questions, answers)
} }
func createSolver(questions chan polar) chan cartesian { func createSolver(questions chan polar) chan cartesian {
answers := make(chan cartesian) answers := make(chan cartesian)
go func() { go func() {
for { for {
polarCoord := <-questions polarCoord := <-questions
Θ := polarCoord.Θ * math.Pi / 180.0 // degrees to radians Θ := polarCoord.Θ * math.Pi / 180.0 // degrees to radians
x := polarCoord.radius * math.Cos(Θ) x := polarCoord.radius * math.Cos(Θ)
y := polarCoord.radius * math.Sin(Θ) y := polarCoord.radius * math.Sin(Θ)
answers <- cartesian{x, y} answers <- cartesian{x, y}
} }
}() }()
return answers return answers
} }
func interact(questions chan polar, answers chan cartesian) { func interact(questions chan polar, answers chan cartesian) {
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
fmt.Println(prompt) fmt.Println(prompt)
for { for {
fmt.Printf("Radius and angle: ") fmt.Printf("Radius and angle: ")
line, err := reader.ReadString('\n') line, err := reader.ReadString('\n')
if err != nil { if err != nil {
break break
} }
line = line[:len(line)-1] // chop of newline character line = line[:len(line)-1] // chop of newline character
if numbers := strings.Fields(line); len(numbers) == 2 { if numbers := strings.Fields(line); len(numbers) == 2 {
polars, err := floatsForStrings(numbers) polars, err := floatsForStrings(numbers)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, "invalid number") fmt.Fprintln(os.Stderr, "invalid number")
continue continue
} }
questions <- polar{polars[0], polars[1]} questions <- polar{polars[0], polars[1]}
coord := <-answers coord := <-answers
fmt.Printf(result, polars[0], polars[1], coord.x, coord.y) fmt.Printf(result, polars[0], polars[1], coord.x, coord.y)
} else { } else {
fmt.Fprintln(os.Stderr, "invalid input") fmt.Fprintln(os.Stderr, "invalid input")
} }
} }
fmt.Println() fmt.Println()
} }
func floatsForStrings(numbers []string) ([]float64, error) { func floatsForStrings(numbers []string) ([]float64, error) {
var floats []float64 var floats []float64
for _, number := range numbers { for _, number := range numbers {
if x, err := strconv.ParseFloat(number, 64); err != nil { if x, err := strconv.ParseFloat(number, 64); err != nil {
return nil, err return nil, err
} else { } else {
floats = append(floats, x) floats = append(floats, x)
} }
} }
return floats, nil return floats, nil
} }
/* Output:
Enter a radius and an angle (in degrees), e.g., 12.5 90, or Ctrl+Z, Enter to qui /* Output:
t. Enter a radius and an angle (in degrees), e.g., 12.5 90, or Ctrl+Z, Enter to qui
Radius and angle: 12.5 90 t.
Polar: radius=12.50 angle=90.00 degrees -- Cartesian: x=0.00 y=12.50 Radius and angle: 12.5 90
Radius and angle: ^Z Polar: radius=12.50 angle=90.00 degrees -- Cartesian: x=0.00 y=12.50
*/ Radius and angle: ^Z
*/

View File

@@ -1,42 +1,43 @@
// goroutines2.go // goroutines2.go
package main package main
import "fmt" import "fmt"
// integer producer: // integer producer:
func numGen(start, count int, out chan<- int) { func numGen(start, count int, out chan<- int) {
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
out <- start out <- start
start = start + count start = start + count
} }
close(out) close(out)
} }
// integer consumer: // integer consumer:
func numEchoRange(in <-chan int, done chan<- bool) { func numEchoRange(in <-chan int, done chan<- bool) {
for num := range in { for num := range in {
fmt.Printf("%d\n", num) fmt.Printf("%d\n", num)
} }
done <- true done <- true
} }
func main() { func main() {
numChan := make(chan int) numChan := make(chan int)
done := make(chan bool) done := make(chan bool)
go numGen(0, 10, numChan) go numGen(0, 10, numChan)
go numEchoRange(numChan, done) go numEchoRange(numChan, done)
<-done <-done
} }
/* Output:
0 /* Output:
10 0
20 10
30 20
40 30
50 40
60 50
70 60
80 70
90 80
*/ 90
*/

View File

@@ -1,29 +1,30 @@
// prod_cons.go // prod_cons.go
/* producer-consumer problem in Go */ /* producer-consumer problem in Go */
package main package main
import "fmt" import "fmt"
var done = make(chan bool) var done = make(chan bool)
var msgs = make(chan int) var msgs = make(chan int)
func produce() { func produce() {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
msgs <- i msgs <- i
} }
done <- true done <- true
} }
func consume() { func consume() {
for { for {
msg := <-msgs msg := <-msgs
fmt.Print(msg, " ") fmt.Print(msg, " ")
} }
} }
func main() { func main() {
go produce() go produce()
go consume() go consume()
<-done <-done
} }
// Output: 0 1 2 3 4 5 6 7 8 9
// Output: 0 1 2 3 4 5 6 7 8 9

View File

@@ -1,23 +1,23 @@
package main package main
import ( import (
"fmt" "fmt"
) )
func main() { func main() {
c := make(chan int) c := make(chan int)
// consumer: // consumer:
go func() { go func() {
for { for {
fmt.Print(<-c, " ") fmt.Print(<-c, " ")
} }
}() }()
// producer: // producer:
for { for {
select { select {
case c <- 0: case c <- 0:
case c <- 1: case c <- 1:
} }
} }
} }

View File

@@ -1,46 +1,46 @@
package main package main
import ( import (
"fmt" "bufio"
"os" "fmt"
"net" "net"
"bufio" "os"
"strings" "strings"
) )
func main() { func main() {
var conn net.Conn var conn net.Conn
var error error var error error
var inputReader *bufio.Reader var inputReader *bufio.Reader
var input string var input string
var clientName string var clientName string
// maak connectie met de server: // maak connectie met de server:
conn, error = net.Dial("tcp", "localhost:50000") conn, error = net.Dial("tcp", "localhost:50000")
checkError(error) checkError(error)
inputReader = bufio.NewReader(os.Stdin) inputReader = bufio.NewReader(os.Stdin)
fmt.Println("First, what is your name?") fmt.Println("First, what is your name?")
clientName, _ = inputReader.ReadString('\n') clientName, _ = inputReader.ReadString('\n')
// fmt.Printf("CLIENTNAME %s",clientName) // fmt.Printf("CLIENTNAME %s",clientName)
trimmedClient := strings.Trim(clientName, "\r\n") // "\r\n" voor Windows, "\n" voor Linux trimmedClient := strings.Trim(clientName, "\r\n") // "\r\n" voor Windows, "\n" voor Linux
for { for {
fmt.Println("What to send to the server? Type Q to quit. Type SH to shutdown server.") fmt.Println("What to send to the server? Type Q to quit. Type SH to shutdown server.")
input, _ = inputReader.ReadString('\n') input, _ = inputReader.ReadString('\n')
trimmedInput := strings.Trim(input, "\r\n") trimmedInput := strings.Trim(input, "\r\n")
// fmt.Printf("input:--%s--",input) // fmt.Printf("input:--%s--",input)
// fmt.Printf("trimmedInput:--%s--",trimmedInput) // fmt.Printf("trimmedInput:--%s--",trimmedInput)
if trimmedInput == "Q" { if trimmedInput == "Q" {
return return
} }
_, error = conn.Write([]byte(trimmedClient + " says: " + trimmedInput)) _, error = conn.Write([]byte(trimmedClient + " says: " + trimmedInput))
checkError(error) checkError(error)
} }
} }
func checkError(error error) { func checkError(error error) {
if error != nil { if error != nil {
panic("Error: " + error.Error()) // terminate program panic("Error: " + error.Error()) // terminate program
} }
} }

View File

@@ -1,19 +1,20 @@
// hello_server.go // hello_server.go
package main package main
import ( import (
"fmt" "fmt"
"net/http" "net/http"
) )
type Hello struct{} type Hello struct{}
func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello!") fmt.Fprint(w, "Hello!")
} }
func main() { func main() {
var h Hello var h Hello
http.ListenAndServe("localhost:4000",h) http.ListenAndServe("localhost:4000", h)
} }
// Output in browser-window with url http://localhost:4000: Hello!
// Output in browser-window with url http://localhost:4000: Hello!

View File

@@ -1,31 +1,31 @@
// httpfetch.go // httpfetch.go
package main package main
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"net/http" "io/ioutil"
"io/ioutil" "log"
"log" "net/http"
"os" "os"
"strings" "strings"
) )
func main() { func main() {
fmt.Print("Give the url from which to read: ") fmt.Print("Give the url from which to read: ")
iread := bufio.NewReader(os.Stdin) iread := bufio.NewReader(os.Stdin)
url, _ := iread.ReadString('\n') url, _ := iread.ReadString('\n')
url = strings.Trim(url," \n\r") // trimming space,etc. url = strings.Trim(url, " \n\r") // trimming space,etc.
// fmt.Println("***", url,"***") // debugging // fmt.Println("***", url,"***") // debugging
res, err := http.Get(url) res, err := http.Get(url)
CheckError(err) CheckError(err)
data, err := ioutil.ReadAll(res.Body) data, err := ioutil.ReadAll(res.Body)
CheckError(err) CheckError(err)
fmt.Printf("Got: %q", string(data)) fmt.Printf("Got: %q", string(data))
} }
func CheckError(err error) { func CheckError(err error) {
if err != nil { if err != nil {
log.Fatalf("Get: %v", err) log.Fatalf("Get: %v", err)
} }
} }

View File

@@ -1,75 +1,75 @@
package main package main
import ( import (
"fmt" "fmt"
"os" "net"
"net" "os"
"strings" "strings"
) )
// Map of the clients: contains: clientname - 1 (active) / 0 - (inactive) // Map of the clients: contains: clientname - 1 (active) / 0 - (inactive)
var mapUsers map[string]int var mapUsers map[string]int
func main() { func main() {
var listener net.Listener var listener net.Listener
var error error var error error
var conn net.Conn var conn net.Conn
mapUsers = make(map[string]int) mapUsers = make(map[string]int)
fmt.Println("Starting the server ...") fmt.Println("Starting the server ...")
// create listener: // create listener:
listener, error = net.Listen("tcp", "localhost:50000") listener, error = net.Listen("tcp", "localhost:50000")
checkError(error) checkError(error)
// listen and accept connections from clients: // listen and accept connections from clients:
for { for {
conn, error = listener.Accept() conn, error = listener.Accept()
checkError(error) checkError(error)
go doServerStuff(conn) go doServerStuff(conn)
} }
} }
func doServerStuff(conn net.Conn) { func doServerStuff(conn net.Conn) {
var buf []byte var buf []byte
var error error var error error
for { for {
buf = make([]byte, 512) buf = make([]byte, 512)
_, error = conn.Read(buf) _, error = conn.Read(buf)
checkError(error) checkError(error)
input := string(buf) input := string(buf)
if strings.Contains(input, ": SH") { if strings.Contains(input, ": SH") {
fmt.Println("Server shutting down.") fmt.Println("Server shutting down.")
os.Exit(0) os.Exit(0)
} }
// op commando WHO: write out mapUsers // op commando WHO: write out mapUsers
if strings.Contains(input, ": WHO") { if strings.Contains(input, ": WHO") {
DisplayList() DisplayList()
} }
// extract clientname: // extract clientname:
ix := strings.Index(input, "says") ix := strings.Index(input, "says")
clName := input[0:ix-1] clName := input[0 : ix-1]
//fmt.Printf("The clientname is ---%s---\n", string(clName)) //fmt.Printf("The clientname is ---%s---\n", string(clName))
// set clientname active in mapUsers: // set clientname active in mapUsers:
mapUsers[string(clName)] = 1 mapUsers[string(clName)] = 1
fmt.Printf("Received data: --%v--", string(buf)) fmt.Printf("Received data: --%v--", string(buf))
} }
} }
// advantage: code is cleaner, // advantage: code is cleaner,
// disadvantage: the server process has to stop at any error: // disadvantage: the server process has to stop at any error:
// a simple return continues in the function where we came from! // a simple return continues in the function where we came from!
func checkError(error error) { func checkError(error error) {
if error != nil { if error != nil {
panic("Error: " + error.Error()) // terminate program panic("Error: " + error.Error()) // terminate program
} }
} }
func DisplayList() { func DisplayList() {
fmt.Println("--------------------------------------------") fmt.Println("--------------------------------------------")
fmt.Println("This is the client list: 1=active, 0=inactive") fmt.Println("This is the client list: 1=active, 0=inactive")
for key, value := range mapUsers { for key, value := range mapUsers {
fmt.Printf("User %s is %d\n", key, value) fmt.Printf("User %s is %d\n", key, value)
} }
fmt.Println("--------------------------------------------") fmt.Println("--------------------------------------------")
} }

View File

@@ -1,110 +1,110 @@
// statistics.go // statistics.go
package main package main
import ( import (
"fmt" "fmt"
"net/http" "log"
"sort" "net/http"
"strings" "sort"
"strconv" "strconv"
"log" "strings"
) )
type statistics struct { type statistics struct {
numbers []float64 numbers []float64
mean float64 mean float64
median float64 median float64
} }
const form = `<html><body><form action="/" method="POST"> const form = `<html><body><form action="/" method="POST">
<label for="numbers">Numbers (comma or space-separated):</label><br> <label for="numbers">Numbers (comma or space-separated):</label><br>
<input type="text" name="numbers" size="30"><br /> <input type="text" name="numbers" size="30"><br />
<input type="submit" value="Calculate"> <input type="submit" value="Calculate">
</form></html></body>` </form></html></body>`
const error = `<p class="error">%s</p>` const error = `<p class="error">%s</p>`
var pageTop = "" var pageTop = ""
var pageBottom = "" var pageBottom = ""
func main() { func main() {
http.HandleFunc("/", homePage) http.HandleFunc("/", homePage)
if err := http.ListenAndServe(":9001", nil); err != nil { if err := http.ListenAndServe(":9001", nil); err != nil {
log.Fatal("failed to start server", err) log.Fatal("failed to start server", err)
} }
} }
func homePage(writer http.ResponseWriter, request *http.Request) { func homePage(writer http.ResponseWriter, request *http.Request) {
writer.Header().Set("Content-Type", "text/html") writer.Header().Set("Content-Type", "text/html")
err := request.ParseForm() // Must be called before writing response err := request.ParseForm() // Must be called before writing response
fmt.Fprint(writer, pageTop, form) fmt.Fprint(writer, pageTop, form)
if err != nil { if err != nil {
fmt.Fprintf(writer, error, err) fmt.Fprintf(writer, error, err)
} else { } else {
if numbers, message, ok := processRequest(request); ok { if numbers, message, ok := processRequest(request); ok {
stats := getStats(numbers) stats := getStats(numbers)
fmt.Fprint(writer, formatStats(stats)) fmt.Fprint(writer, formatStats(stats))
} else if message != "" { } else if message != "" {
fmt.Fprintf(writer, error, message) fmt.Fprintf(writer, error, message)
} }
} }
fmt.Fprint(writer, pageBottom) fmt.Fprint(writer, pageBottom)
} }
func processRequest(request *http.Request) ([]float64, string, bool) { func processRequest(request *http.Request) ([]float64, string, bool) {
var numbers []float64 var numbers []float64
var text string var text string
if slice, found := request.Form["numbers"]; found && len(slice) > 0 { if slice, found := request.Form["numbers"]; found && len(slice) > 0 {
//处理如果网页中输入的是中文逗号 //处理如果网页中输入的是中文逗号
if strings.Contains(slice[0], "&#65292") { if strings.Contains(slice[0], "&#65292") {
text = strings.Replace(slice[0], "&#65292;", " ", -1) text = strings.Replace(slice[0], "&#65292;", " ", -1)
} else { } else {
text = strings.Replace(slice[0], ",", " ", -1) text = strings.Replace(slice[0], ",", " ", -1)
} }
for _, field := range strings.Fields(text) { for _, field := range strings.Fields(text) {
if x, err := strconv.ParseFloat(field, 64); err != nil { if x, err := strconv.ParseFloat(field, 64); err != nil {
return numbers, "'" + field + "' is invalid", false return numbers, "'" + field + "' is invalid", false
} else { } else {
numbers = append(numbers, x) numbers = append(numbers, x)
} }
} }
} }
if len(numbers) == 0 { if len(numbers) == 0 {
return numbers, "", false // no data first time form is shown return numbers, "", false // no data first time form is shown
} }
return numbers, "", true return numbers, "", true
} }
func getStats(numbers []float64) (stats statistics) { func getStats(numbers []float64) (stats statistics) {
stats.numbers = numbers stats.numbers = numbers
sort.Float64s(stats.numbers) sort.Float64s(stats.numbers)
stats.mean = sum(numbers) / float64(len(numbers)) stats.mean = sum(numbers) / float64(len(numbers))
stats.median = median(numbers) stats.median = median(numbers)
return return
} }
func sum(numbers []float64) (total float64) { func sum(numbers []float64) (total float64) {
for _, x := range numbers { for _, x := range numbers {
total += x total += x
} }
return return
} }
func median(numbers []float64) float64 { func median(numbers []float64) float64 {
middle := len(numbers)/2 middle := len(numbers) / 2
result := numbers[middle] result := numbers[middle]
if len(numbers)%2 == 0 { if len(numbers)%2 == 0 {
result = (result + numbers[middle-1]) / 2 result = (result + numbers[middle-1]) / 2
} }
return result return result
} }
func formatStats(stats statistics) string { func formatStats(stats statistics) string {
return fmt.Sprintf(`<table border="1"> return fmt.Sprintf(`<table border="1">
<tr><th colspan="2">Results</th></tr> <tr><th colspan="2">Results</th></tr>
<tr><td>Numbers</td><td>%v</td></tr> <tr><td>Numbers</td><td>%v</td></tr>
<tr><td>Count</td><td>%d</td></tr> <tr><td>Count</td><td>%d</td></tr>
<tr><td>Mean</td><td>%f</td></tr> <tr><td>Mean</td><td>%f</td></tr>
<tr><td>Median</td><td>%f</td></tr> <tr><td>Median</td><td>%f</td></tr>
</table>`, stats.numbers, len(stats.numbers), stats.mean, stats.median) </table>`, stats.numbers, len(stats.numbers), stats.mean, stats.median)
} }

View File

@@ -1,29 +1,30 @@
// template_validation_recover.go // template_validation_recover.go
package main package main
import ( import (
"text/template" "fmt"
"fmt" "log"
"log" "text/template"
) )
func main() { func main() {
tOk := template.New("ok") tOk := template.New("ok")
tErr := template.New("error_template") tErr := template.New("error_template")
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
log.Printf("run time panic: %v", err) log.Printf("run time panic: %v", err)
} }
}() }()
//a valid template, so no panic with Must: //a valid template, so no panic with Must:
template.Must(tOk.Parse("/* and a comment */ some static text: {{ .Name }}")) template.Must(tOk.Parse("/* and a comment */ some static text: {{ .Name }}"))
fmt.Println("The first one parsed OK.") fmt.Println("The first one parsed OK.")
fmt.Println("The next one ought to fail.") fmt.Println("The next one ought to fail.")
template.Must(tErr.Parse(" some static text {{ .Name }")) template.Must(tErr.Parse(" some static text {{ .Name }"))
} }
/* Output:
The first one parsed OK. /* Output:
The next one ought to fail. The first one parsed OK.
2011/10/27 10:56:27 run time panic: template: error_template:1: unexpected "}" in command The next one ought to fail.
*/ 2011/10/27 10:56:27 run time panic: template: error_template:1: unexpected "}" in command
*/

View File

@@ -1,33 +1,34 @@
// twitter_status_json.go // twitter_status_json.go
package main package main
import ( import (
"net/http" "encoding/json"
"fmt" "fmt"
"encoding/json" "io/ioutil"
"io/ioutil" "net/http"
) )
type Status struct { type Status struct {
Text string Text string
} }
type User struct { type User struct {
Status Status Status Status
} }
func main() { func main() {
/* perform an HTTP request for the twitter status of user: Googland */ /* perform an HTTP request for the twitter status of user: Googland */
res, _:= http.Get("http://twitter.com/users/Googland.json") res, _ := http.Get("http://twitter.com/users/Googland.json")
/* initialize the structure of the JSON response */ /* initialize the structure of the JSON response */
user := User{Status{""}} user := User{Status{""}}
/* unmarshal the JSON into our structures */ /* unmarshal the JSON into our structures */
temp, _ := ioutil.ReadAll(res.Body) temp, _ := ioutil.ReadAll(res.Body)
body := []byte(temp) body := []byte(temp)
json.Unmarshal(body, &user) json.Unmarshal(body, &user)
fmt.Printf("status: %s", user.Status.Text) fmt.Printf("status: %s", user.Status.Text)
} }
/* Output:
status: Robot cars invade California, on orders from Google: /* Output:
Google has been testing self-driving cars ... http://bit.ly/cbtpUN http://retwt.me/97p status: Robot cars invade California, on orders from Google:
*/ Google has been testing self-driving cars ... http://bit.ly/cbtpUN http://retwt.me/97p
*/

View File

@@ -1,24 +1,24 @@
// webhello2.go // webhello2.go
package main package main
import ( import (
"net/http" "fmt"
"fmt" "net/http"
"strings" "strings"
) )
func helloHandler(w http.ResponseWriter, r *http.Request) { func helloHandler(w http.ResponseWriter, r *http.Request) {
remPartOfURL := r.URL.Path[len("/hello/"):] //get everything after the /hello/ part of the URL remPartOfURL := r.URL.Path[len("/hello/"):] //get everything after the /hello/ part of the URL
fmt.Fprintf(w, "Hello %s!", remPartOfURL) fmt.Fprintf(w, "Hello %s!", remPartOfURL)
} }
func shouthelloHandler(w http.ResponseWriter, r *http.Request) { func shouthelloHandler(w http.ResponseWriter, r *http.Request) {
remPartOfURL := r.URL.Path[len("/shouthello/"):] //get everything after the /shouthello/ part of the URL remPartOfURL := r.URL.Path[len("/shouthello/"):] //get everything after the /shouthello/ part of the URL
fmt.Fprintf(w, "Hello %s!", strings.ToUpper(remPartOfURL)) fmt.Fprintf(w, "Hello %s!", strings.ToUpper(remPartOfURL))
} }
func main() { func main() {
http.HandleFunc("/hello/", helloHandler) http.HandleFunc("/hello/", helloHandler)
http.HandleFunc("/shouthello/", shouthelloHandler) http.HandleFunc("/shouthello/", shouthelloHandler)
http.ListenAndServe("localhost:9999", nil) http.ListenAndServe("localhost:9999", nil)
} }