update book code

This commit is contained in:
Unknwon
2015-03-03 12:25:25 -05:00
parent b8c82ba4e5
commit eab1d98ba8
465 changed files with 15392 additions and 1572 deletions

View File

@@ -0,0 +1,15 @@
package main
import "fmt"
type C struct {
x float32;
int;
string;
}
func main() {
c := C{3.14, 7, "hello"}
fmt.Println(c.x, c.int, c.string) // output: 3.14 7 hello
fmt.Println(c) // output: {3.14 7 hello}
}

View File

@@ -0,0 +1,19 @@
// celsius.go
package main
import (
"fmt"
"strconv"
)
type Celsius float64
func (c Celsius) String() string {
return "The temperature is: " + strconv.FormatFloat(float64(c),'f', 1, 32) + " °C"
}
func main() {
var c Celsius = 18.36
fmt.Println(c)
}
// The temperature is: 18.4 °C

View File

@@ -0,0 +1,36 @@
package main
import "fmt"
type Day int
const (
MO Day = iota
TU
WE
TH
FR
SA
SU
)
var dayName = []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
func (day Day) String() string {
return dayName[day]
}
func main() {
var th Day = 3
fmt.Printf("The 3rd day is: %s\n", th)
// If index > 6: panic: runtime error: index out of range
// but use the enumerated type to work with valid values:
var day = SU;
fmt.Println(day); // prints Sunday
fmt.Println(0, MO, 1, TU)
}
/* Output:
The 3rd day is: Thursday
Sunday
0 Monday 1 Tuesday
*/

View File

@@ -0,0 +1,25 @@
// methods1.go
package main
import "fmt"
/* basic data structure upon with we'll define methods */
type employee struct {
salary float32
}
/* a method which will add a specified percent to an
employees salary */
func (this *employee) giveRaise(pct float32) {
this.salary += this.salary * pct
}
func main() {
/* create an employee instance */
var e = new(employee)
e.salary = 100000;
/* call our method */
e.giveRaise(0.04)
fmt.Printf("Employee now makes %f", e.salary)
}
// Employee now makes 104000.000000

View File

@@ -0,0 +1,40 @@
package main
import "fmt"
type Base struct {
id string
}
func (b *Base) Id() string {
return b.id
}
func (b *Base) SetId(id string) {
b.id = id
}
type Person struct {
Base
FirstName string
LastName string
}
type Employee struct {
Person
salary float32
}
func main() {
idjb := Base{"007"}
jb := Person{idjb, "James", "Bond"}
e := &Employee{jb, 100000.}
fmt.Printf("ID of our hero: %v\n", e.Id())
// Change the id:
e.SetId("007B")
fmt.Printf("The new ID of our hero: %v\n", e.Id())
}
/* Output:
ID of our hero: 007
The new ID of our hero: 007B
*/

View File

@@ -0,0 +1,59 @@
// inheritance_car.go
package main
import (
"fmt"
)
type Engine interface {
Start()
Stop()
}
type Car struct {
wheelCount int
Engine
}
// define a behavior for Car
func (car Car) numberOfWheels() int {
return car.wheelCount
}
type Mercedes struct {
Car //anonymous field Car
}
// a behavior only available for the Mercedes
func (m *Mercedes) sayHiToMerkel() {
fmt.Println("Hi Angela!")
}
func (c *Car) Start() {
fmt.Println("Car is started")
}
func (c *Car) Stop() {
fmt.Println("Car is stopped")
}
func (c *Car) GoToWorkIn() {
// get in car
c.Start();
// drive to work
c.Stop();
// get out of car
}
func main() {
m := Mercedes{Car{4, nil}}
fmt.Println("A Mercedes has this many wheels: ", m.numberOfWheels())
m.GoToWorkIn()
m.sayHiToMerkel()
}
/* Output:
A Mercedes has this many wheels: 4
Car is started
Car is stopped
Hi Angela!
*/

View File

@@ -0,0 +1,23 @@
/*
iteration_list.go:12: cannot define new methods on non-local type list.List
iteration_list.go:17: lst.Iter undefined (type *list.List has no field or method Iter)
---- Build file exited with code 1
*/
package main
import "container/list"
// cannot define new methods on non-local type list.List
// List iterator:
func (p *list.List) Iter() {
}
func main() {
lst := new(list.List)
for _ = range lst.Iter() {
}
}

View File

@@ -0,0 +1,29 @@
// magic.go
package main
import "fmt"
type Base struct{}
func (Base) Magic() { fmt.Print("base magic ") }
func (self Base) MoreMagic() {
self.Magic()
self.Magic()
}
type Voodoo struct {
Base
}
func (Voodoo) Magic() { fmt.Println("voodoo magic") }
func main() {
v := new(Voodoo)
v.Magic()
v.MoreMagic()
}
/* Output:
voodoo magic
base magic base magic
*/

View File

@@ -0,0 +1,45 @@
// Q15.go
package main
import (
"fmt"
"./stack/stack"
)
func main() {
st1 := new(stack.Stack)
fmt.Printf("%v\n", st1)
st1.Push(3)
fmt.Printf("%v\n", st1)
st1.Push(7)
fmt.Printf("%v\n", st1)
st1.Push(10)
fmt.Printf("%v\n", st1)
st1.Push(99)
fmt.Printf("%v\n", st1)
p := st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
}
/* Output:
[0:3]
[0:3] [1:7]
[0:3] [1:7] [2:10]
[0:3] [1:7] [2:10] [3:99]
Popped 99
[0:3] [1:7] [2:10]
Popped 10
[0:3] [1:7]
Popped 7
[0:3]
Popped 3
*/

View File

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

View File

@@ -0,0 +1,49 @@
package main
import (
"fmt"
"math"
)
type Point struct {
X, Y float64
}
type Point3 struct {
X, Y, Z float64
}
type Polar struct {
R, T float64
}
func Abs(p *Point) float64 {
return math.Sqrt(float64(p.X*p.X + p.Y*p.Y))
}
func Scale(p *Point,s float64) (q Point) {
q.X = p.X * s
q.Y = p.Y * s
return
}
func main() {
p1 := new(Point)
p1.X = 3
p1.Y = 4
fmt.Printf("The length of the vector p1 is: %f\n", Abs(p1) )
p2:= &Point{4, 5}
fmt.Printf("The length of the vector p2 is: %f\n", Abs(p2) )
q := Scale(p1, 5)
fmt.Printf("The length of the vector q is: %f\n", Abs(&q) )
fmt.Printf("Point p1 scaled by 5 has the following coordinates: X %f - Y %f", q.X, q.Y)
}
/* Output:
The length of the vector p1 is: 5.000000
The length of the vector p2 is: 6.403124
The length of the vector q is: 25.000000
Point p1 scaled by 5 has the following coordinates: X 15.000000 - Y 20.000000
*/

View File

@@ -0,0 +1,54 @@
// float64 is necessary as input to math.Sqrt()
package main
import (
"fmt"
"math"
)
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, T float64
}
func (p Polar) Abs() float64 { return p.R }
func main() {
p1 := new(Point)
p1.X = 3
p1.Y = 4
fmt.Printf("The length of the vector p1 is: %f\n", p1.Abs())
p2:= &Point{4, 5}
fmt.Printf("The length of the vector p2 is: %f\n", p2.Abs() )
p1.Scale(5)
fmt.Printf("The length of the vector p1 after scaling is: %f\n", p1.Abs() )
fmt.Printf("Point p1 after scaling has the following coordinates: X %f - Y %f", p1.X, p1.Y)
}
/* 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
*/

View File

@@ -0,0 +1,28 @@
// rectangle.go
package main
import "fmt"
type Rectangle struct {
length, width int
}
func (r *Rectangle) Area() int {
return r.length * r.width
}
func (r *Rectangle) Perimeter() int {
return 2* (r.length + r.width)
}
func main() {
r1 := Rectangle{4, 3}
fmt.Println("Rectangle is: ", r1)
fmt.Println("Rectangle area is: ", r1.Area())
fmt.Println("Rectangle perimeter is: ", r1.Perimeter())
}
/* Output:
Rectangle is: {4 3}
Rectangle area is: 12
Rectangle perimeter is: 14
*/

View File

@@ -0,0 +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
}

View File

@@ -0,0 +1,64 @@
package main
import (
"fmt"
"strconv"
)
const LIMIT = 4
type Stack [LIMIT]int
func main() {
st1 := new(Stack)
fmt.Printf("%v\n", st1)
st1.Push(3)
fmt.Printf("%v\n", st1)
st1.Push(7)
fmt.Printf("%v\n", st1)
st1.Push(10)
fmt.Printf("%v\n", st1)
st1.Push(99)
fmt.Printf("%v\n", st1)
p := st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
}
// put value on first position which contains 0, starting from bottom
func (st *Stack) Push(n int) {
for ix, v := range st {
if v == 0 {
st[ix] = n
break
}
}
}
// take value from first position which contains !=0, starting from top
func (st *Stack) Pop() int {
v := 0
for ix:= len(st)-1; ix>=0; ix-- {
if v=st[ix]; v!=0 {
st[ix] = 0
return v
}
}
return 0
}
func (st Stack) String() string {
str := ""
for ix, v := range st {
str += "[" + strconv.Itoa(ix) + ":" + strconv.Itoa(v) + "] "
}
return str
}

View File

@@ -0,0 +1,59 @@
// stack_struct.go
package main
import (
"fmt"
"strconv"
)
const LIMIT = 4
type Stack struct {
ix int // first free position, so data[ix] == 0
data [LIMIT]int
}
func main() {
st1 := new(Stack)
fmt.Printf("%v\n", st1)
st1.Push(3)
fmt.Printf("%v\n", st1)
st1.Push(7)
fmt.Printf("%v\n", st1)
st1.Push(10)
fmt.Printf("%v\n", st1)
st1.Push(99)
fmt.Printf("%v\n", st1)
p := st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
p = st1.Pop()
fmt.Printf("Popped %d\n", p)
fmt.Printf("%v\n", st1)
}
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

@@ -0,0 +1,40 @@
// Output:
// Eastern Standard time
// Universal Greenwich time
// Central Standard time
package main
import "fmt"
type TZ int
const (
HOUR TZ = 60 * 60
UTC TZ = 0 * HOUR
EST TZ = -5 * HOUR
CST TZ = -6 * HOUR
)
var timeZones = map[TZ]string { UTC:"Universal Greenwich time",
EST:"Eastern Standard time",
CST:"Central Standard time" }
func (tz TZ) String() string { // Method on TZ (not ptr)
for name, zone := range timeZones {
if tz == name {
return zone
}
}
return ""
}
func main() {
fmt.Println(EST) // Print* knows about method String() of type TZ
fmt.Println(0 * HOUR)
fmt.Println(-6 * HOUR)
}
/* Output:
Eastern Standard time
Universal Greenwich time
Central Standard time
*/

View File

@@ -0,0 +1,19 @@
package main
import "fmt"
type T struct {
a int
b float32
c string
}
func main() {
t := &T{ 7, -2.35, "abc\tdef" }
fmt.Printf("%v\n", t)
}
func (t *T) String() string {
return fmt.Sprintf("%d / %f / %q", t.a, t.b, t.c)
}
// Output: 7 / -2.350000 / "abc\tdef"

View File

@@ -0,0 +1,44 @@
package main
import (
"fmt"
"time"
)
type Address struct {
Street string
HouseNumber uint32
HouseNumberAddOn string
POBox string
ZipCode string
City string
Country string
}
type VCard struct {
FirstName string
LastName string
NickName string
BirtDate time.Time
Photo string
Addresses map[string]*Address
}
func main() {
addr1 := &Address{"Elfenstraat", 12, "", "", "2600", "Mechelen", "België" }
addr2 := &Address{"Heideland", 28, "", "", "2640", "Mortsel", "België" }
addrs := make(map[string]*Address)
addrs["youth"] = addr1
addrs["now"] = addr2
birthdt := time.Date(1956, 1, 17, 15, 4, 5, 0, time.Local)
photo := "MyDocuments/MyPhotos/photo1.jpg"
vcard := &VCard{"Ivo", "Balbaert", "", birthdt, photo, addrs}
fmt.Printf("Here is the full VCard: %v\n", vcard)
fmt.Printf("My Addresses are:\n %v\n %v", addr1, addr2)
}
/* Output:
Here is the full VCard: &{Ivo Balbaert Sun Jan 17 15:04:05 +0000 1956 MyDocuments/MyPhotos/photo1.jpg map[now:0x126d57c0 youth:0x126d5500]}
My Addresses are:
&{Elfenstraat 12 2600 Mechelen België}
&{Heideland 28 2640 Mortsel België}
*/

View File

@@ -0,0 +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()
}

View File

@@ -0,0 +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!
*/

View File

@@ -0,0 +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 !
*/

View File

@@ -0,0 +1,68 @@
// 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

@@ -0,0 +1,51 @@
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

@@ -0,0 +1,57 @@
// 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

@@ -0,0 +1,29 @@
// 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
*/

View File

@@ -0,0 +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()
}

View File

@@ -0,0 +1,62 @@
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

@@ -0,0 +1,59 @@
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

@@ -0,0 +1,28 @@
// 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

@@ -0,0 +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
*/

View File

@@ -0,0 +1,89 @@
// 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

@@ -0,0 +1,43 @@
// 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

@@ -0,0 +1,34 @@
// 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

@@ -0,0 +1,61 @@
// 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

@@ -0,0 +1,74 @@
// 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

@@ -0,0 +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)) }

View File

@@ -0,0 +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)
}

View File

@@ -0,0 +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
}

View File

@@ -0,0 +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)
}

View File

@@ -0,0 +1,53 @@
// 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 + q)
case token == "-":
q := calc1.Pop()
p := calc1.Pop()
fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p - q)
case token == "*":
q := calc1.Pop()
p := calc1.Pop()
fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p * q)
case token == "/":
q := calc1.Pop()
p := calc1.Pop()
fmt.Printf("The result of %d %s %d = %d\n", p, token, q, p / q)
default:
fmt.Println("No valid input")
}
}
}

View File

@@ -0,0 +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))
}
}

View File

@@ -0,0 +1,41 @@
// 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}

View File

@@ -0,0 +1,10 @@
// goprogram.go
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World!")
}

Binary file not shown.

View File

@@ -0,0 +1,20 @@
// 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]
*/

View File

@@ -0,0 +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, "!")
}

View File

@@ -0,0 +1,4 @@
"The ABC of Go";25.5;1500
"Functional Programming with Go";56;280
"Go for It";45.9;356
"The Go Way";55;500

View File

@@ -0,0 +1,67 @@
// 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}
*/

View File

@@ -0,0 +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")
}

View File

@@ -0,0 +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
}

View File

@@ -0,0 +1,3 @@
hello, world in a file
this is a second line
this is a third line

Binary file not shown.

View File

@@ -0,0 +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
// count number of spaces, nr of words is +1
nrwords += strings.Count(input, " ") + 1
nrlines++
}

View File

@@ -0,0 +1,6 @@
include $(GOROOT)/src/Make.inc
TARG=strev
GOFILES=\
string_reverse.go\
include $(GOROOT)/src/Make.pkg

View File

@@ -0,0 +1,44 @@
// 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

@@ -0,0 +1,44 @@
// 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

@@ -0,0 +1,34 @@
// 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

@@ -0,0 +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))
}
*/

View File

@@ -0,0 +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)
}
}

View File

@@ -0,0 +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)
}

View File

@@ -0,0 +1,22 @@
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

@@ -0,0 +1,21 @@
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

@@ -0,0 +1,45 @@
// 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

@@ -0,0 +1,45 @@
// 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

@@ -0,0 +1,59 @@
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

@@ -0,0 +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
}

View File

@@ -0,0 +1,35 @@
// 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

@@ -0,0 +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)
}

View File

@@ -0,0 +1,42 @@
// 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

@@ -0,0 +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)
}
}
}

View File

@@ -0,0 +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)
}
}

View File

@@ -0,0 +1,31 @@
// 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

@@ -0,0 +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
}

View File

@@ -0,0 +1,58 @@
// 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

@@ -0,0 +1,101 @@
// 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

@@ -0,0 +1,42 @@
// 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

@@ -0,0 +1,29 @@
// 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

@@ -0,0 +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:
}
}
}

View File

@@ -0,0 +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
}
}

View File

@@ -0,0 +1,19 @@
// 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

@@ -0,0 +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)
}
}

View File

@@ -0,0 +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("--------------------------------------------")
}

View File

@@ -0,0 +1,104 @@
// 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
if slice, found := request.Form["numbers"]; found && len(slice) > 0 {
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

@@ -0,0 +1,29 @@
// 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
*/

View File

@@ -0,0 +1,33 @@
// 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
*/

View File

@@ -0,0 +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)
}

42
eBook/exercises/chapter_4/count_characters.go Normal file → Executable file
View File

@@ -1,22 +1,22 @@
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
// count number of characters:
str1 := "asSASA ddd dsjkdsjs dk"
fmt.Printf("The number of bytes in string str1 is %d\n",len(str1))
fmt.Printf("The number of characters in string str1 is %d\n",utf8.RuneCountInString(str1))
str2 := "asSASA ddd dsjkdsjsこん dk"
fmt.Printf("The number of bytes in string str2 is %d\n",len(str2))
fmt.Printf("The number of characters in string str2 is %d",utf8.RuneCountInString(str2))
}
/* Output:
The number of bytes in string str1 is 22
The number of characters in string str1 is 22
The number of bytes in string str2 is 28
The number of characters in string str2 is 24
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
// count number of characters:
str1 := "asSASA ddd dsjkdsjs dk"
fmt.Printf("The number of bytes in string str1 is %d\n",len(str1))
fmt.Printf("The number of characters in string str1 is %d\n",utf8.RuneCountInString(str1))
str2 := "asSASA ddd dsjkdsjsこん dk"
fmt.Printf("The number of bytes in string str2 is %d\n",len(str2))
fmt.Printf("The number of characters in string str2 is %d",utf8.RuneCountInString(str2))
}
/* Output:
The number of bytes in string str1 is 22
The number of characters in string str1 is 22
The number of bytes in string str2 is 28
The number of characters in string str2 is 24
*/

16
eBook/exercises/chapter_4/divby0.go Normal file → Executable file
View File

@@ -1,8 +1,8 @@
package main
func main() {
a, b := 10, 0
c := a / b // panic: runtime error: integer divide by zero
print(c)
}
package main
func main() {
a, b := 10, 0
c := a / b // panic: runtime error: integer divide by zero
print(c)
}

34
eBook/exercises/chapter_4/function_calls_function.go Normal file → Executable file
View File

@@ -1,18 +1,18 @@
package main
var a string // global scope
func main() {
a = "G"
print(a)
f1()
}
func f1() {
a := "O" // new local variable a, only scoped within f1() !
print(a)
f2()
}
func f2() {
print(a) // global variable is taken
}
package main
var a string // global scope
func main() {
a = "G"
print(a)
f1()
}
func f1() {
a := "O" // new local variable a, only scoped within f1() !
print(a)
f2()
}
func f2() {
print(a) // global variable is taken
}
// GOG

36
eBook/exercises/chapter_4/global_scope.go Normal file → Executable file
View File

@@ -1,19 +1,19 @@
package main
var a = "G" // global scope
func main() {
n()
m()
n()
}
func n() {
print(a)
}
func m() {
a = "O" // simple assignment: global a gets a new value
print(a)
}
package main
var a = "G" // global scope
func main() {
n()
m()
n()
}
func n() {
print(a)
}
func m() {
a = "O" // simple assignment: global a gets a new value
print(a)
}
// GOO

32
eBook/exercises/chapter_4/local_scope.go Normal file → Executable file
View File

@@ -1,17 +1,17 @@
package main
var a = "G" // global (package) scope
func main() {
n()
m()
n()
}
func n() {
print(a)
}
func m() {
a := "O" // new local variable a is declared
print(a)
}
package main
var a = "G" // global (package) scope
func main() {
n()
m()
n()
}
func n() {
print(a)
}
func m() {
a := "O" // new local variable a is declared
print(a)
}
// GOG

42
eBook/exercises/chapter_5/bitwise_complement.go Normal file → Executable file
View File

@@ -1,22 +1,22 @@
package main
import "fmt"
func main() {
for i:=0; i <= 10; i ++ {
fmt.Printf("the complement of %b is: %b\n", i, ^i)
}
}
/* Output:
the complement of 0 is: -1
the complement of 1 is: -10
the complement of 10 is: -11
the complement of 11 is: -100
the complement of 100 is: -101
the complement of 101 is: -110
the complement of 110 is: -111
the complement of 111 is: -1000
the complement of 1000 is: -1001
the complement of 1001 is: -1010
the complement of 1010 is: -1011
package main
import "fmt"
func main() {
for i:=0; i <= 10; i ++ {
fmt.Printf("the complement of %b is: %b\n", i, ^i)
}
}
/* Output:
the complement of 0 is: -1
the complement of 1 is: -10
the complement of 10 is: -11
the complement of 11 is: -100
the complement of 100 is: -101
the complement of 101 is: -110
the complement of 110 is: -111
the complement of 111 is: -1000
the complement of 1000 is: -1001
the complement of 1001 is: -1010
the complement of 1010 is: -1011
*/

46
eBook/exercises/chapter_5/fizzbuzz.go Normal file → Executable file
View File

@@ -1,24 +1,24 @@
package main
import "fmt"
const (
FIZZ=3
BUZZ=5
FIZZBUZZ=15
)
func main() {
for i:=0; i <= 100; i++ {
switch {
case i%FIZZBUZZ==0:
fmt.Println("FizzBuzz")
case i%FIZZ==0:
fmt.Println("Fizz")
case i%BUZZ==0:
fmt.Println("Buzz")
default:
fmt.Println(i)
}
}
package main
import "fmt"
const (
FIZZ=3
BUZZ=5
FIZZBUZZ=15
)
func main() {
for i:=0; i <= 100; i++ {
switch {
case i%FIZZBUZZ==0:
fmt.Println("FizzBuzz")
case i%FIZZ==0:
fmt.Println("Fizz")
case i%BUZZ==0:
fmt.Println("Buzz")
default:
fmt.Println(i)
}
}
}

32
eBook/exercises/chapter_5/for_character.go Normal file → Executable file
View File

@@ -1,17 +1,17 @@
package main
func main() {
// 1 - use 2 nested for loops
for i:=1; i <= 25; i++ {
for j:=1; j <=i; j++ {
print("G")
}
println()
}
// 2 - use only one for loop and string concatenation
str := "G"
for i:=1; i <= 25; i++ {
println(str)
str += "G"
}
package main
func main() {
// 1 - use 2 nested for loops
for i:=1; i <= 25; i++ {
for j:=1; j <=i; j++ {
print("G")
}
println()
}
// 2 - use only one for loop and string concatenation
str := "G"
for i:=1; i <= 25; i++ {
println(str)
str += "G"
}
}

30
eBook/exercises/chapter_5/for_loop.go Normal file → Executable file
View File

@@ -1,16 +1,16 @@
package main
import "fmt"
func main() {
// 1:
for i:=0; i < 15; i++ {
fmt.Printf("The counter is at %d\n", i)
}
// 2:
i := 0
START:
fmt.Printf("The counter is at %d\n", i)
i++
if i < 15 { goto START }
package main
import "fmt"
func main() {
// 1:
for i:=0; i < 15; i++ {
fmt.Printf("The counter is at %d\n", i)
}
// 2:
i := 0
START:
fmt.Printf("The counter is at %d\n", i)
i++
if i < 15 { goto START }
}

28
eBook/exercises/chapter_5/i_undefined.go Normal file → Executable file
View File

@@ -1,14 +1,14 @@
// i_undefined.go
package main
import (
"fmt"
)
func main() {
var i int
for i=0; i<10; i++ {
fmt.Printf("%v\n", i)
}
fmt.Printf("%v\n", i) //<-- compile error: undefined i
}
// i_undefined.go
package main
import (
"fmt"
)
func main() {
var i int
for i=0; i<10; i++ {
fmt.Printf("%v\n", i)
}
fmt.Printf("%v\n", i) //<-- compile error: undefined i
}

32
eBook/exercises/chapter_5/multiple_for.go Normal file → Executable file
View File

@@ -1,17 +1,17 @@
// multiple_for.go
package main
import "fmt"
func main() {
//multiple initialization; a consolidated bool expression with && and ||; multiple incrementation
for i, j, s := 0, 5, "a"; i < 3 && j < 100 && s != "aaaaa"; i, j, s = i+1,
j+1, s + "a" {
fmt.Println("Value of i, j, s:", i, j, s)
}
}
/* Output:
Value of i, j, s: 0 5 a
Value of i, j, s: 1 6 aa
Value of i, j, s: 2 7 aaa
// multiple_for.go
package main
import "fmt"
func main() {
//multiple initialization; a consolidated bool expression with && and ||; multiple incrementation
for i, j, s := 0, 5, "a"; i < 3 && j < 100 && s != "aaaaa"; i, j, s = i+1,
j+1, s + "a" {
fmt.Println("Value of i, j, s:", i, j, s)
}
}
/* Output:
Value of i, j, s: 0 5 a
Value of i, j, s: 1 6 aa
Value of i, j, s: 2 7 aaa
*/

52
eBook/exercises/chapter_5/rectangle_stars.go Normal file → Executable file
View File

@@ -1,26 +1,26 @@
// rectangle_stars.go
package main
import "fmt"
func main() {
w, h := 20, 10
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
fmt.Print("*")
}
fmt.Println()
}
}
/* Output:
********************
********************
********************
********************
********************
********************
********************
********************
********************
********************
*/
// rectangle_stars.go
package main
import "fmt"
func main() {
w, h := 20, 10
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
fmt.Print("*")
}
fmt.Println()
}
}
/* Output:
********************
********************
********************
********************
********************
********************
********************
********************
********************
********************
*/

32
eBook/exercises/chapter_5/season.go Normal file → Executable file
View File

@@ -1,17 +1,17 @@
package main
import "fmt"
func main() {
fmt.Printf(Season(3))
}
func Season(month int) string {
switch month {
case 12,1,2: return "Winter"
case 3,4,5: return "Spring"
case 6,7,8: return "Summer"
case 9,10,11: return "Autumn"
}
return "Season unknown"
package main
import "fmt"
func main() {
fmt.Printf(Season(3))
}
func Season(month int) string {
switch month {
case 12,1,2: return "Winter"
case 3,4,5: return "Spring"
case 6,7,8: return "Summer"
case 9,10,11: return "Autumn"
}
return "Season unknown"
}

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