Merge pull request #322 from appleboy/patch-8

fix: coding style and file format for chapter 11, 12, 13, 14 and 15.
This commit is contained in:
无闻
2017-02-10 23:34:01 -05:00
committed by GitHub
63 changed files with 2662 additions and 2622 deletions

View File

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

View File

@@ -1,25 +1,25 @@
package main
import (
"fmt"
"./float64"
)
func main() {
f1 := float64.NewFloat64Array()
f1.Fill(10)
fmt.Printf("Before sorting %s\n", f1)
float64.Sort(f1)
fmt.Printf("After sorting %s\n", f1)
if float64.IsSorted(f1) {
fmt.Println("The float64 array is sorted!")
} else {
fmt.Println("The float64 array is NOT sorted!")
}
}
/* Output:
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 }
The float64 array is sorted!
*/
package main
import (
"./float64"
"fmt"
)
func main() {
f1 := float64.NewFloat64Array()
f1.Fill(10)
fmt.Printf("Before sorting %s\n", f1)
float64.Sort(f1)
fmt.Printf("After sorting %s\n", f1)
if float64.IsSorted(f1) {
fmt.Println("The float64 array is sorted!")
} else {
fmt.Println("The float64 array is NOT sorted!")
}
}
/* Output:
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 }
The float64 array is sorted!
*/

View File

@@ -1,46 +1,46 @@
// interface_nil.go
package main
import "fmt"
type Any interface {}
type Anything struct {}
func main() {
any := getAny()
if any == nil {
fmt.Println("any is nil")
} else {
fmt.Println("any is not nil")
}
/*
// to get the inner value:
anything := any.(*Anything)
if anything == nil {
fmt.Println("anything is nil")
} else {
fmt.Println("anything is not nil")
}
*/
}
func getAny() Any {
return getAnything()
}
func getAnything() *Anything {
return nil
}
/* Output:
any is not nil
WHY?
you would perhaps expect: any is nil,because getAnything() returns that
BUT:
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.
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).
To get the inner value of any, use: anything := any.(*Anything)
now anything contains nil !
*/
// interface_nil.go
package main
import "fmt"
type Any interface{}
type Anything struct{}
func main() {
any := getAny()
if any == nil {
fmt.Println("any is nil")
} else {
fmt.Println("any is not nil")
}
/*
// to get the inner value:
anything := any.(*Anything)
if anything == nil {
fmt.Println("anything is nil")
} else {
fmt.Println("anything is not nil")
}
*/
}
func getAny() Any {
return getAnything()
}
func getAnything() *Anything {
return nil
}
/* Output:
any is not nil
WHY?
you would perhaps expect: any is nil,because getAnything() returns that
BUT:
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.
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).
To get the inner value of any, use: anything := any.(*Anything)
now anything contains nil !
*/

View File

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

View File

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

View File

@@ -1,57 +1,58 @@
// interfaces_poly2.go
package main
import (
"fmt"
"math"
)
type Shaper interface {
Area() float32
}
type Square struct {
side float32
}
func (sq *Square) Area() float32 {
return sq.side * sq.side
}
type Rectangle struct {
length, width float32
}
func (r Rectangle) Area() float32 {
return r.length * r.width
}
type Circle struct {
radius float32
}
func (c *Circle) Area() float32 {
return math.Pi * c.radius * c.radius
}
func main() {
r := Rectangle{5, 3} // Area() of Rectangle needs a value
q := &Square{5} // Area() of Square needs a pointer
c := &Circle{2.5}
fmt.Println("Looping through shapes for area ...")
// shapes := []Shaper{Shaper(r), Shaper(q), Shaper(c)}
shapes := []Shaper{r, q, c}
for n, _ := range shapes {
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}
Area of this shape is: 15
Shape details: &{5}
Area of this shape is: 25
Shape details: &{2.5}
Area of this shape is: 19.634954
*/
// interfaces_poly2.go
package main
import (
"fmt"
"math"
)
type Shaper interface {
Area() float32
}
type Square struct {
side float32
}
func (sq *Square) Area() float32 {
return sq.side * sq.side
}
type Rectangle struct {
length, width float32
}
func (r Rectangle) Area() float32 {
return r.length * r.width
}
type Circle struct {
radius float32
}
func (c *Circle) Area() float32 {
return math.Pi * c.radius * c.radius
}
func main() {
r := Rectangle{5, 3} // Area() of Rectangle needs a value
q := &Square{5} // Area() of Square needs a pointer
c := &Circle{2.5}
fmt.Println("Looping through shapes for area ...")
// shapes := []Shaper{Shaper(r), Shaper(q), Shaper(c)}
shapes := []Shaper{r, q, c}
for n := range shapes {
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}
Area of this shape is: 15
Shape details: &{5}
Area of this shape is: 25
Shape details: &{2.5}
Area of this shape is: 19.634954
*/

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,28 +1,30 @@
// min_interface.go
package min
type Miner interface {
Len() int
ElemIx(ix int) interface{}
Less(i, j int) bool
}
func Min(data Miner) interface{} {
min := data.ElemIx(0)
for i:=1; i < data.Len(); i++ {
if data.Less(i, i-1) {
min = data.ElemIx(i)
}
}
return min
}
type IntArray []int
func (p IntArray) Len() int { return len(p) }
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) }
func (p StringArray) ElemIx(ix int) interface{} { return p[ix] }
func (p StringArray) Less(i, j int) bool { return p[i] < p[j] }
// min_interface.go
package min
type Miner interface {
Len() int
ElemIx(ix int) interface{}
Less(i, j int) bool
}
func Min(data Miner) interface{} {
min := data.ElemIx(0)
for i := 1; i < data.Len(); i++ {
if data.Less(i, i-1) {
min = data.ElemIx(i)
}
}
return min
}
type IntArray []int
func (p IntArray) Len() int { return len(p) }
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) }
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
package main
import (
"fmt"
"./min"
)
func ints() {
data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
a := min.IntArray(data) //conversion to type IntArray
m := min.Min(a)
fmt.Printf("The minimum of the array is: %v\n", m)
}
func strings() {
data := []string{"ddd", "eee", "bbb", "ccc", "aaa"}
a := min.StringArray(data)
m := min.Min(a)
fmt.Printf("The minimum of the array is: %v\n", m)
}
func main() {
ints()
strings()
}
/* Output:
The minimum of the array is: -5467984
The minimum of the array is: aaa
*/
// minmain.go
package main
import (
"./min"
"fmt"
)
func ints() {
data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
a := min.IntArray(data) //conversion to type IntArray
m := min.Min(a)
fmt.Printf("The minimum of the array is: %v\n", m)
}
func strings() {
data := []string{"ddd", "eee", "bbb", "ccc", "aaa"}
a := min.StringArray(data)
m := min.Min(a)
fmt.Printf("The minimum of the array is: %v\n", m)
}
func main() {
ints()
strings()
}
/* Output:
The minimum of the array is: -5467984
The minimum of the array is: aaa
*/

View File

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

View File

@@ -1,43 +1,50 @@
// print.go
package main
import (
"os"
"strconv"
)
type Stringer interface {
String() string
}
type Celsius float64
func (c Celsius) String() string {
return strconv.FormatFloat(float64(c),'f', 1, 64) + " °C"
}
type Day int
var dayName = []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
func (day Day) String() string {
return dayName[day]
}
func print(args ...interface{}) {
for i, arg := range args {
if i > 0 {os.Stdout.WriteString(" ")}
switch a := arg.(type) { // type switch
case Stringer: os.Stdout.WriteString(a.String())
case int: os.Stdout.WriteString(strconv.Itoa(a))
case string: os.Stdout.WriteString(a)
// more types
default: os.Stdout.WriteString("???")
}
}
}
func main() {
print(Day(1), "was", Celsius(18.36)) // Tuesday was 18.4 °C
}
// Tuesday was 18.4 °C
// print.go
package main
import (
"os"
"strconv"
)
type Stringer interface {
String() string
}
type Celsius float64
func (c Celsius) String() string {
return strconv.FormatFloat(float64(c), 'f', 1, 64) + " °C"
}
type Day int
var dayName = []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
func (day Day) String() string {
return dayName[day]
}
func print(args ...interface{}) {
for i, arg := range args {
if i > 0 {
os.Stdout.WriteString(" ")
}
switch a := arg.(type) { // type switch
case Stringer:
os.Stdout.WriteString(a.String())
case int:
os.Stdout.WriteString(strconv.Itoa(a))
case string:
os.Stdout.WriteString(a)
// more types
default:
os.Stdout.WriteString("???")
}
}
}
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
package main
import (
"fmt"
)
type Simpler interface {
Get() int
Put(int)
}
type Simple struct {
i int
}
func (p *Simple) Get() int {
return p.i
}
func (p *Simple) Put(u int) {
p.i = u
}
func fI(it Simpler) int {
it.Put(5)
return it.Get()
}
func main() {
var s Simple
fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer
}
// Output: 5
// simple_interface.go
package main
import (
"fmt"
)
type Simpler interface {
Get() int
Put(int)
}
type Simple struct {
i int
}
func (p *Simple) Get() int {
return p.i
}
func (p *Simple) Put(u int) {
p.i = u
}
func fI(it Simpler) int {
it.Put(5)
return it.Get()
}
func main() {
var s Simple
fmt.Println(fI(&s)) // &s is required because Get() is defined with a receiver type pointer
}
// Output: 5

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,41 +1,42 @@
// degob.go
package main
import (
"bufio"
"fmt"
"encoding/gob"
"log"
"os"
)
type Address struct {
Type string
City string
Country string
}
type VCard struct {
FirstName string
LastName string
Addresses []*Address
Remark string
}
var content string
var vc VCard
func main() {
// using a decoder:
file, _ := os.Open("vcard.gob")
defer file.Close()
inReader := bufio.NewReader(file)
dec := gob.NewDecoder(inReader)
err := dec.Decode(&vc)
if err != nil {
log.Println("Error in decoding gob")
}
fmt.Println(vc)
}
// Output:
// {Jan Kersschot [0x12642e60 0x12642e80] none}
// degob.go
package main
import (
"bufio"
"encoding/gob"
"fmt"
"log"
"os"
)
type Address struct {
Type string
City string
Country string
}
type VCard struct {
FirstName string
LastName string
Addresses []*Address
Remark string
}
var content string
var vc VCard
func main() {
// using a decoder:
file, _ := os.Open("vcard.gob")
defer file.Close()
inReader := bufio.NewReader(file)
dec := gob.NewDecoder(inReader)
err := dec.Decode(&vc)
if err != nil {
log.Println("Error in decoding gob")
}
fmt.Println(vc)
}
// Output:
// {Jan Kersschot [0x12642e60 0x12642e80] none}

View File

@@ -1,20 +1,21 @@
// hash_md5.go
package main
import (
"fmt";
"crypto/md5"
"io"
)
func main() {
hasher := md5.New()
b := []byte{}
io.WriteString(hasher, "test")
fmt.Printf("Result: %x\n", hasher.Sum(b))
fmt.Printf("Result: %d\n", hasher.Sum(b))
}
/* Output:
Result: 098f6bcd4621d373cade4e832627b4f6
Result: [9 143 107 205 70 33 211 115 202 222 78 131 38 39 180 246]
*/
// hash_md5.go
package main
import (
"crypto/md5"
"fmt"
"io"
)
func main() {
hasher := md5.New()
b := []byte{}
io.WriteString(hasher, "test")
fmt.Printf("Result: %x\n", hasher.Sum(b))
fmt.Printf("Result: %d\n", hasher.Sum(b))
}
/* Output:
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
package main
import (
"fmt"
"os"
"strings"
)
func main() {
who := "World"
if len(os.Args) > 1 { // os.Args[0] == hello_who
who = strings.Join(os.Args[1:], " ")
}
fmt.Println("Hello", who, "!")
}
// hello_who.go
package main
import (
"fmt"
"os"
"strings"
)
func main() {
who := "World"
if len(os.Args) > 1 { // os.Args[0] == hello_who
who = strings.Join(os.Args[1:], " ")
}
fmt.Println("Hello", who, "!")
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,36 +1,37 @@
// Q28_word_letter_count.go
package main
import (
"fmt"
"bufio"
"os"
"strings"
)
var nrchars, nrwords, nrlines int
func main() {
nrchars, nrwords, nrlines = 0, 0, 0
inputReader := bufio.NewReader(os.Stdin)
fmt.Println("Please enter some input, type S to stop: ")
for {
input, err := inputReader.ReadString('\n')
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:")
fmt.Printf("Number of characters: %d\n", nrchars)
fmt.Printf("Number of words: %d\n", nrwords)
fmt.Printf("Number of lines: %d\n", nrlines)
os.Exit(0)
}
Counters(input)
}
}
func Counters(input string) {
nrchars += len(input) - 2 // -2 for \r\n
nrwords += len(strings.Fields(input))
nrlines++
}
// Q28_word_letter_count.go
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
var nrchars, nrwords, nrlines int
func main() {
nrchars, nrwords, nrlines = 0, 0, 0
inputReader := bufio.NewReader(os.Stdin)
fmt.Println("Please enter some input, type S to stop: ")
for {
input, err := inputReader.ReadString('\n')
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:")
fmt.Printf("Number of characters: %d\n", nrchars)
fmt.Printf("Number of words: %d\n", nrwords)
fmt.Printf("Number of lines: %d\n", nrlines)
os.Exit(0)
}
Counters(input)
}
}
func Counters(input string) {
nrchars += len(input) - 2 // -2 for \r\n
nrwords += len(strings.Fields(input))
nrlines++
}

View File

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

View File

@@ -1,44 +1,45 @@
// panic_defer_convint.go
package main
import (
"fmt"
"math"
)
func main() {
l := int64(15000)
if i, err := IntFromInt64(l); err!= nil {
fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error())
} else {
fmt.Printf("%d converted to an int32 is %d", l, i)
}
fmt.Println()
l = int64(math.MaxInt32 + 15000)
if i, err := IntFromInt64(l); err!= nil {
fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error())
} else {
fmt.Printf("%d converted to an int32 is %d", l, i)
}
}
func ConvertInt64ToInt(l int64) int {
if math.MinInt32 <= l && l <= math.MaxInt32 {
return int(l)
}
panic(fmt.Sprintf("%d is out of the int32 range", l))
}
func IntFromInt64(l int64) (i int, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("%v", e)
}
}()
i = ConvertInt64ToInt(l)
return i, nil
}
/* Output:
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
*/
// panic_defer_convint.go
package main
import (
"fmt"
"math"
)
func main() {
l := int64(15000)
if i, err := IntFromInt64(l); err != nil {
fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error())
} else {
fmt.Printf("%d converted to an int32 is %d", l, i)
}
fmt.Println()
l = int64(math.MaxInt32 + 15000)
if i, err := IntFromInt64(l); err != nil {
fmt.Printf("The conversion of %d to an int32 resulted in an error: %s", l, err.Error())
} else {
fmt.Printf("%d converted to an int32 is %d", l, i)
}
}
func ConvertInt64ToInt(l int64) int {
if math.MinInt32 <= l && l <= math.MaxInt32 {
return int(l)
}
panic(fmt.Sprintf("%d is out of the int32 range", l))
}
func IntFromInt64(l int64) (i int, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("%v", e)
}
}()
i = ConvertInt64ToInt(l)
return i, nil
}
/* Output:
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
package main
import (
"fmt"
)
func badCall() {
a, b := 10, 0
n := a / b
fmt.Println(n)
}
func test() {
defer func() {
if e := recover(); e != nil {
fmt.Printf("Panicing %s\r\n", e);
}
}()
badCall()
fmt.Printf("After bad call\r\n");
}
func main() {
fmt.Printf("Calling test\r\n");
test()
fmt.Printf("Test completed\r\n");
}
/* Output:
Calling test
Panicing runtime error: integer divide by zero
Test completed
*/
// recover_divbyzero.go
package main
import (
"fmt"
)
func badCall() {
a, b := 10, 0
n := a / b
fmt.Println(n)
}
func test() {
defer func() {
if e := recover(); e != nil {
fmt.Printf("Panicing %s\r\n", e)
}
}()
badCall()
fmt.Printf("After bad call\r\n")
}
func main() {
fmt.Printf("Calling test\r\n")
test()
fmt.Printf("Test completed\r\n")
}
/* Output:
Calling test
Panicing runtime error: integer divide by zero
Test completed
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,59 +1,60 @@
package main
import (
"fmt"
)
type Any interface{}
type EvalFunc func(Any) (Any, Any)
func main() {
fibFunc := func(state Any) (Any, Any) {
os := state.([]uint64)
v1 := os[0]
v2 := os[1]
ns := []uint64{v2, v1 + v2}
return v1, ns
}
fib := BuildLazyUInt64Evaluator(fibFunc, []uint64{0, 1})
for i := 0; i < 10; i++ {
fmt.Printf("Fib nr %v: %v\n", i, fib())
}
}
func BuildLazyEvaluator(evalFunc EvalFunc, initState Any) func() Any {
retValChan := make(chan Any)
loopFunc := func() {
var actState Any = initState
var retVal Any
for {
retVal, actState = evalFunc(actState)
retValChan <- retVal
}
}
retFunc := func() Any {
return <-retValChan
}
go loopFunc()
return retFunc
}
func BuildLazyUInt64Evaluator(evalFunc EvalFunc, initState Any) func() uint64 {
ef := BuildLazyEvaluator(evalFunc, initState)
return func() uint64 {
return ef().(uint64)
}
}
/* Output:
Fib nr 0: 0
Fib nr 1: 1
Fib nr 2: 1
Fib nr 3: 2
Fib nr 4: 3
Fib nr 5: 5
Fib nr 6: 8
Fib nr 7: 13
Fib nr 8: 21
Fib nr 9: 34
*/
package main
import (
"fmt"
)
type Any interface{}
type EvalFunc func(Any) (Any, Any)
func main() {
fibFunc := func(state Any) (Any, Any) {
os := state.([]uint64)
v1 := os[0]
v2 := os[1]
ns := []uint64{v2, v1 + v2}
return v1, ns
}
fib := BuildLazyUInt64Evaluator(fibFunc, []uint64{0, 1})
for i := 0; i < 10; i++ {
fmt.Printf("Fib nr %v: %v\n", i, fib())
}
}
func BuildLazyEvaluator(evalFunc EvalFunc, initState Any) func() Any {
retValChan := make(chan Any)
loopFunc := func() {
var actState Any = initState
var retVal Any
for {
retVal, actState = evalFunc(actState)
retValChan <- retVal
}
}
retFunc := func() Any {
return <-retValChan
}
go loopFunc()
return retFunc
}
func BuildLazyUInt64Evaluator(evalFunc EvalFunc, initState Any) func() uint64 {
ef := BuildLazyEvaluator(evalFunc, initState)
return func() uint64 {
return ef().(uint64)
}
}
/* Output:
Fib nr 0: 0
Fib nr 1: 1
Fib nr 2: 1
Fib nr 3: 2
Fib nr 4: 3
Fib nr 5: 5
Fib nr 6: 8
Fib nr 7: 13
Fib nr 8: 21
Fib nr 9: 34
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,58 +1,59 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "fmt"
type Request struct {
a, b int
replyc chan int // reply channel inside the Request
}
type binOp func(a, b int) int
func run(op binOp, req *Request) {
req.replyc <- op(req.a, req.b)
}
func (r *Request) String() string {
return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc)
}
func server(op binOp, service chan *Request, quit chan bool) {
for {
select {
case req := <-service:
go run(op, req)
case <-quit:
return // stop infinite loop
}
}
}
func startServer(op binOp) (service chan *Request, quit chan bool) {
service = make(chan *Request)
quit = make(chan bool)
go server(op, service, quit)
return service, quit
}
func main() {
adder, quit := startServer(func(a, b int) int { return a + b })
// make requests:
req1 := &Request{3, 4, make(chan int)}
req2 := &Request{150, 250, make(chan int)}
// send requests on the service channel
adder <- req1
adder <- req2
// ask for the results: ( method String() is called )
fmt.Println(req1, req2)
// shutdown server:
quit <- true
fmt.Print("done")
}
/* output:
3+4=7 150+250=400
done
*/
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "fmt"
type Request struct {
a, b int
replyc chan int // reply channel inside the Request
}
type binOp func(a, b int) int
func run(op binOp, req *Request) {
req.replyc <- op(req.a, req.b)
}
func (r *Request) String() string {
return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc)
}
func server(op binOp, service chan *Request, quit chan bool) {
for {
select {
case req := <-service:
go run(op, req)
case <-quit:
return // stop infinite loop
}
}
}
func startServer(op binOp) (service chan *Request, quit chan bool) {
service = make(chan *Request)
quit = make(chan bool)
go server(op, service, quit)
return service, quit
}
func main() {
adder, quit := startServer(func(a, b int) int { return a + b })
// make requests:
req1 := &Request{3, 4, make(chan int)}
req2 := &Request{150, 250, make(chan int)}
// send requests on the service channel
adder <- req1
adder <- req2
// ask for the results: ( method String() is called )
fmt.Println(req1, req2)
// shutdown server:
quit <- true
fmt.Print("done")
}
/* output:
3+4=7 150+250=400
done
*/

View File

@@ -1,101 +1,102 @@
// polartocartesian.go
package main
import (
"bufio"
"fmt"
"math"
"os"
"runtime"
"strconv"
"strings"
)
type polar struct {
radius float64
Θ float64
}
type cartesian struct {
x float64
y float64
}
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."
func init() {
if runtime.GOOS == "windows" {
prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter")
} else { // Unix-like
prompt = fmt.Sprintf(prompt, "Ctrl+D")
}
}
func main() {
questions := make(chan polar)
defer close(questions)
answers := createSolver(questions)
defer close(answers)
interact(questions, answers)
}
func createSolver(questions chan polar) chan cartesian {
answers := make(chan cartesian)
go func() {
for {
polarCoord := <-questions
Θ := polarCoord.Θ * math.Pi / 180.0 // degrees to radians
x := polarCoord.radius * math.Cos(Θ)
y := polarCoord.radius * math.Sin(Θ)
answers <- cartesian{x, y}
}
}()
return answers
}
func interact(questions chan polar, answers chan cartesian) {
reader := bufio.NewReader(os.Stdin)
fmt.Println(prompt)
for {
fmt.Printf("Radius and angle: ")
line, err := reader.ReadString('\n')
if err != nil {
break
}
line = line[:len(line)-1] // chop of newline character
if numbers := strings.Fields(line); len(numbers) == 2 {
polars, err := floatsForStrings(numbers)
if err != nil {
fmt.Fprintln(os.Stderr, "invalid number")
continue
}
questions <- polar{polars[0], polars[1]}
coord := <-answers
fmt.Printf(result, polars[0], polars[1], coord.x, coord.y)
} else {
fmt.Fprintln(os.Stderr, "invalid input")
}
}
fmt.Println()
}
func floatsForStrings(numbers []string) ([]float64, error) {
var floats []float64
for _, number := range numbers {
if x, err := strconv.ParseFloat(number, 64); err != nil {
return nil, err
} else {
floats = append(floats, x)
}
}
return floats, nil
}
/* Output:
Enter a radius and an angle (in degrees), e.g., 12.5 90, or Ctrl+Z, Enter to qui
t.
Radius and angle: 12.5 90
Polar: radius=12.50 angle=90.00 degrees -- Cartesian: x=0.00 y=12.50
Radius and angle: ^Z
*/
// polartocartesian.go
package main
import (
"bufio"
"fmt"
"math"
"os"
"runtime"
"strconv"
"strings"
)
type polar struct {
radius float64
Θ float64
}
type cartesian struct {
x float64
y float64
}
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."
func init() {
if runtime.GOOS == "windows" {
prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter")
} else { // Unix-like
prompt = fmt.Sprintf(prompt, "Ctrl+D")
}
}
func main() {
questions := make(chan polar)
defer close(questions)
answers := createSolver(questions)
defer close(answers)
interact(questions, answers)
}
func createSolver(questions chan polar) chan cartesian {
answers := make(chan cartesian)
go func() {
for {
polarCoord := <-questions
Θ := polarCoord.Θ * math.Pi / 180.0 // degrees to radians
x := polarCoord.radius * math.Cos(Θ)
y := polarCoord.radius * math.Sin(Θ)
answers <- cartesian{x, y}
}
}()
return answers
}
func interact(questions chan polar, answers chan cartesian) {
reader := bufio.NewReader(os.Stdin)
fmt.Println(prompt)
for {
fmt.Printf("Radius and angle: ")
line, err := reader.ReadString('\n')
if err != nil {
break
}
line = line[:len(line)-1] // chop of newline character
if numbers := strings.Fields(line); len(numbers) == 2 {
polars, err := floatsForStrings(numbers)
if err != nil {
fmt.Fprintln(os.Stderr, "invalid number")
continue
}
questions <- polar{polars[0], polars[1]}
coord := <-answers
fmt.Printf(result, polars[0], polars[1], coord.x, coord.y)
} else {
fmt.Fprintln(os.Stderr, "invalid input")
}
}
fmt.Println()
}
func floatsForStrings(numbers []string) ([]float64, error) {
var floats []float64
for _, number := range numbers {
if x, err := strconv.ParseFloat(number, 64); err != nil {
return nil, err
} else {
floats = append(floats, x)
}
}
return floats, nil
}
/* Output:
Enter a radius and an angle (in degrees), e.g., 12.5 90, or Ctrl+Z, Enter to qui
t.
Radius and angle: 12.5 90
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
package main
import "fmt"
// integer producer:
func numGen(start, count int, out chan<- int) {
for i := 0; i < count; i++ {
out <- start
start = start + count
}
close(out)
}
// integer consumer:
func numEchoRange(in <-chan int, done chan<- bool) {
for num := range in {
fmt.Printf("%d\n", num)
}
done <- true
}
func main() {
numChan := make(chan int)
done := make(chan bool)
go numGen(0, 10, numChan)
go numEchoRange(numChan, done)
<-done
}
/* Output:
0
10
20
30
40
50
60
70
80
90
*/
// goroutines2.go
package main
import "fmt"
// integer producer:
func numGen(start, count int, out chan<- int) {
for i := 0; i < count; i++ {
out <- start
start = start + count
}
close(out)
}
// integer consumer:
func numEchoRange(in <-chan int, done chan<- bool) {
for num := range in {
fmt.Printf("%d\n", num)
}
done <- true
}
func main() {
numChan := make(chan int)
done := make(chan bool)
go numGen(0, 10, numChan)
go numEchoRange(numChan, done)
<-done
}
/* Output:
0
10
20
30
40
50
60
70
80
90
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,29 +1,30 @@
// template_validation_recover.go
package main
import (
"text/template"
"fmt"
"log"
)
func main() {
tOk := template.New("ok")
tErr := template.New("error_template")
defer func() {
if err := recover(); err != nil {
log.Printf("run time panic: %v", err)
}
}()
//a valid template, so no panic with Must:
template.Must(tOk.Parse("/* and a comment */ some static text: {{ .Name }}"))
fmt.Println("The first one parsed OK.")
fmt.Println("The next one ought to fail.")
template.Must(tErr.Parse(" some static text {{ .Name }"))
}
/* Output:
The first one parsed OK.
The next one ought to fail.
2011/10/27 10:56:27 run time panic: template: error_template:1: unexpected "}" in command
*/
// template_validation_recover.go
package main
import (
"fmt"
"log"
"text/template"
)
func main() {
tOk := template.New("ok")
tErr := template.New("error_template")
defer func() {
if err := recover(); err != nil {
log.Printf("run time panic: %v", err)
}
}()
//a valid template, so no panic with Must:
template.Must(tOk.Parse("/* and a comment */ some static text: {{ .Name }}"))
fmt.Println("The first one parsed OK.")
fmt.Println("The next one ought to fail.")
template.Must(tErr.Parse(" some static text {{ .Name }"))
}
/* Output:
The first one parsed OK.
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
package main
import (
"net/http"
"fmt"
"encoding/json"
"io/ioutil"
)
type Status struct {
Text string
}
type User struct {
Status Status
}
func main() {
/* perform an HTTP request for the twitter status of user: Googland */
res, _:= http.Get("http://twitter.com/users/Googland.json")
/* initialize the structure of the JSON response */
user := User{Status{""}}
/* unmarshal the JSON into our structures */
temp, _ := ioutil.ReadAll(res.Body)
body := []byte(temp)
json.Unmarshal(body, &user)
fmt.Printf("status: %s", user.Status.Text)
}
/* Output:
status: Robot cars invade California, on orders from Google:
Google has been testing self-driving cars ... http://bit.ly/cbtpUN http://retwt.me/97p
*/
// twitter_status_json.go
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type Status struct {
Text string
}
type User struct {
Status Status
}
func main() {
/* perform an HTTP request for the twitter status of user: Googland */
res, _ := http.Get("http://twitter.com/users/Googland.json")
/* initialize the structure of the JSON response */
user := User{Status{""}}
/* unmarshal the JSON into our structures */
temp, _ := ioutil.ReadAll(res.Body)
body := []byte(temp)
json.Unmarshal(body, &user)
fmt.Printf("status: %s", user.Status.Text)
}
/* Output:
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
package main
import (
"net/http"
"fmt"
"strings"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
remPartOfURL := r.URL.Path[len("/hello/"):] //get everything after the /hello/ part of the URL
fmt.Fprintf(w, "Hello %s!", remPartOfURL)
}
func shouthelloHandler(w http.ResponseWriter, r *http.Request) {
remPartOfURL := r.URL.Path[len("/shouthello/"):] //get everything after the /shouthello/ part of the URL
fmt.Fprintf(w, "Hello %s!", strings.ToUpper(remPartOfURL))
}
func main() {
http.HandleFunc("/hello/", helloHandler)
http.HandleFunc("/shouthello/", shouthelloHandler)
http.ListenAndServe("localhost:9999", nil)
}
// webhello2.go
package main
import (
"fmt"
"net/http"
"strings"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
remPartOfURL := r.URL.Path[len("/hello/"):] //get everything after the /hello/ part of the URL
fmt.Fprintf(w, "Hello %s!", remPartOfURL)
}
func shouthelloHandler(w http.ResponseWriter, r *http.Request) {
remPartOfURL := r.URL.Path[len("/shouthello/"):] //get everything after the /shouthello/ part of the URL
fmt.Fprintf(w, "Hello %s!", strings.ToUpper(remPartOfURL))
}
func main() {
http.HandleFunc("/hello/", helloHandler)
http.HandleFunc("/shouthello/", shouthelloHandler)
http.ListenAndServe("localhost:9999", nil)
}