Last active
August 29, 2015 14:05
-
-
Save jitomesky/1a463a0bfeb3ec3770a7 to your computer and use it in GitHub Desktop.
A Tour of Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
func Sqrt(x float64) float64 { | |
z := float64(1.0) | |
for { | |
z_new := z - ( (z*z - x) / (2 * z)) | |
if math.Abs(z - z_new) < 1e-12 { | |
break | |
} | |
z = z_new | |
} | |
return z | |
} | |
func main() { | |
fmt.Println(Sqrt(2)) | |
fmt.Println(math.Sqrt(2)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 配列の宣言方法 | |
package main | |
import "fmt" | |
func main() { | |
p := []int{2, 3, 5, 7, 11, 13} | |
fmt.Println("p ==", p) | |
for i := 0; i < len(p); i++ { | |
fmt.Printf("p[%d] == %d\n", i, p[i]) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// makeで配列を作る | |
// 引数の2番目は長さ | |
// 引数の3番目はキャパシティ | |
// 配列の大きさは変えられるが、その大きさはキャパシティのサイズを超えられない | |
package main | |
import "fmt" | |
func main() { | |
a := make([]int, 5) | |
printSlice("a", a) | |
b := make([]int, 0, 5) | |
printSlice("b", b) | |
c := b[:2] | |
printSlice("c", c) | |
d := c[2:5] | |
printSlice("d", d) | |
} | |
func printSlice(s string, x []int) { | |
fmt.Printf("%s len=%d cap=%d %v\n", | |
s, len(x), cap(x), x) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// rangeは拡張forの様に使える | |
package main | |
import "fmt" | |
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} | |
func main() { | |
for i, v := range pow { | |
fmt.Printf("2**%d = %d\n", i, v) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// rangeは拡張forの様に使える | |
package main | |
import "fmt" | |
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} | |
func main() { | |
for _, v := range pow { | |
fmt.Printf("%d\n", v) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"code.google.com/p/go-tour/pic" | |
) | |
func Pic(dx, dy int) [][]uint8 { | |
pic := make([][]uint8,dy) | |
for i:=0; i<len(pic); i++ { | |
pic[i] = make([]uint8,dx) | |
} | |
for yi,_ := range pic { | |
for xi,_ := range pic[0]{ | |
pic[yi][xi] = uint8(xi^yi) | |
} | |
} | |
return pic | |
} | |
func main() { | |
pic.Show(Pic) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
<del>2次元配列のrangeをとると、1次元に直されて帰ってくる</del> | |
makeでこのように宣言すると、yが6,xが0の2次元配列として確保される | |
結果 | |
0 | |
1 | |
2 | |
3 | |
4 | |
5 | |
*/ | |
package main | |
import ( | |
"fmt" | |
) | |
func main() { | |
pic := make([][]uint8,2*3) | |
for yi,_ := range pic { | |
fmt.Println(yi) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// JavaのHashMapの用に使える。newではなくmakeで作る | |
package main | |
import "fmt" | |
type Vertex struct { | |
Lat, Long float64 | |
} | |
var m map[string]Vertex | |
func main() { | |
m = make(map[string]Vertex) | |
m["Bell Labs"] = Vertex{ | |
40.68433, -74.39967, | |
} | |
fmt.Println(m["Bell Labs"]) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// mapの要素存在確認は、2つめの戻り値で確認する | |
package main | |
import "fmt" | |
func main() { | |
m := make(map[string]int) | |
m["Answer"] = 42 | |
fmt.Println("The value:", m["Answer"]) | |
m["Answer"] = 48 | |
fmt.Println("The value:", m["Answer"]) | |
delete(m, "Answer") | |
fmt.Println("The value:", m["Answer"]) | |
v, ok := m["Answer"] | |
fmt.Println("The value:", v, "Present?", ok) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 問題がわかりづらい | |
// 引数から単語を切り出して、出現回数を記録する | |
package main | |
import ( | |
"code.google.com/p/go-tour/wc" | |
"strings" | |
) | |
func WordCount(s string) map[string]int { | |
m := map[string]int{} | |
ws := strings.Fields(s) | |
for _,w := range(ws){ | |
if val,ok := m[w]; ok == true{ | |
m[w] = val + 1 | |
}else{ | |
m[w] = 1 | |
} | |
} | |
return m | |
} | |
func main() { | |
wc.Test(WordCount) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 簡単な関数なら変数に定義できる(無名関数もどき?) | |
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
func main() { | |
hypot := func(x, y float64) float64 { | |
return math.Sqrt(x*x + y*y) | |
} | |
fmt.Println(hypot(3, 4)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 関数クロージャー | |
// 関数のなかで関数を返すと、それを入れた変数を関数にして使える | |
// クロージャーなので、関数内の変数は保持される | |
package main | |
import "fmt" | |
func adder() func(int) int { | |
sum := 0 | |
return func(x int) int { | |
sum += x | |
return sum | |
} | |
} | |
func main() { | |
pos, neg := adder(), adder() | |
for i := 0; i < 10; i++ { | |
fmt.Println( | |
pos(i), | |
neg(-2*i), | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
// fibonacci is a function that returns | |
// a function that returns an int. | |
func fibonacci() func() int { | |
fn1 := 0 | |
fn2 := 1 | |
return func() int { | |
fn := fn1 | |
fn1 = fn2 | |
fn2 = fn + fn1 | |
return fn | |
} | |
} | |
func main() { | |
f := fibonacci() | |
for i := 0; i < 10; i++ { | |
fmt.Println(f()) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// switch | |
// breakはいらない。fallthroughをつけるとスルーできる | |
package main | |
import ( | |
"fmt" | |
"runtime" | |
) | |
func main() { | |
fmt.Print("Go runs on ") | |
switch os := runtime.GOOS; os { | |
case "darwin": | |
fmt.Println("OS X.") | |
case "linux": | |
fmt.Println("Linux.") | |
default: | |
// freebsd, openbsd, | |
// plan9, windows... | |
fmt.Printf("%s.", os) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Output | |
// (1.2599210498948732+0i) | |
// (2+0i) | |
package main | |
import ( | |
"fmt" | |
"math/cmplx" | |
) | |
func Cbrt(x complex128) complex128 { | |
z := complex128(1.0) | |
for diff := complex128(1.0); cmplx.Abs(diff) > 1e-10; { | |
diff = (cmplx.Pow(z,3) - x) / (3 * cmplx.Pow(z,2)) | |
z -= diff | |
} | |
return z | |
} | |
func main() { | |
fmt.Println(Cbrt(2)) | |
fmt.Println(cmplx.Pow(Cbrt(2),3)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// クラスはないので、structでメソッドを定義する | |
// 引数に(v *Vertex)をとることで、Vertex構造体のメソッドに慣れる? | |
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
type Vertex struct { | |
X, Y float64 | |
} | |
func (v *Vertex) Abs() float64 { | |
return math.Sqrt(v.X*v.X + v.Y*v.Y) | |
} | |
func main() { | |
v := &Vertex{3, 4} | |
fmt.Println(v.Abs()) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 実際には、自分で定義した型であれば、メソッドを定義できる | |
// 実質的なクラスの作り方はこれ? | |
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
type MyFloat float64 | |
func (f MyFloat) Abs() float64 { | |
if f < 0 { | |
return float64(-f) | |
} | |
return float64(f) | |
} | |
func main() { | |
f := MyFloat(-math.Sqrt2) | |
fmt.Println(f.Abs()) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// (v *Vertex)はポインタ参照なので値を変更できる | |
// (v Vertex)は値参照なので、読むことはできるが、変更を反映できない | |
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
type Vertex struct { | |
X, Y float64 | |
} | |
func (v *Vertex) Scale(f float64) { | |
v.X = v.X * f | |
v.Y = v.Y * f | |
} | |
func (v *Vertex) Abs() float64 { | |
return math.Sqrt(v.X*v.X + v.Y*v.Y) | |
} | |
func main() { | |
v := &Vertex{3, 4} | |
v.Scale(5) | |
fmt.Println(v, v.Abs()) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// インターフェース型は、そこに列挙したメソッドが実装された値(structやtype)を入れられる | |
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
type Abser interface { | |
Abs() float64 | |
} | |
func main() { | |
var a Abser | |
f := MyFloat(-math.Sqrt2) | |
v := Vertex{3, 4} | |
a = f // a MyFloat implements Abser | |
a = &v // a *Vertex implements Abser | |
// In the following line, v is a Vertex (not *Vertex) | |
// and does NOT implement Abser. | |
a = v | |
fmt.Println(a.Abs()) | |
} | |
type MyFloat float64 | |
func (f MyFloat) Abs() float64 { | |
if f < 0 { | |
return float64(-f) | |
} | |
return float64(f) | |
} | |
type Vertex struct { | |
X, Y float64 | |
} | |
func (v *Vertex) Abs() float64 { | |
return math.Sqrt(v.X*v.X + v.Y*v.Y) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// エラーはErrorメソッドを実装すればよい | |
package main | |
import ( | |
"fmt" | |
"time" | |
) | |
type MyError struct { | |
When time.Time | |
What string | |
} | |
func (e *MyError) Error() string { | |
return fmt.Sprintf("at %v, %s", | |
e.When, e.What) | |
} | |
func run() error { | |
return &MyError{ | |
time.Now(), | |
"it didn't work", | |
} | |
} | |
func main() { | |
if err := run(); err != nil { | |
fmt.Println(err) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
type ErrNegativeSqrt float64 | |
func (e ErrNegativeSqrt) Error() string{ | |
return fmt.Sprintf("cannot Sqrt negative number: %f",float64(e)) | |
} | |
func Sqrt(f float64) (float64, error) { | |
if f < 0.0 { | |
return 0.0, ErrNegativeSqrt(f) | |
} | |
z := float64(1.0) | |
for { | |
z_new := z - ( (z*z - f) / (2 * z)) | |
if math.Abs(z - z_new) < 1e-12 { | |
break | |
} | |
z = z_new | |
} | |
return z, nil | |
} | |
func main() { | |
fmt.Println(Sqrt(2)) | |
fmt.Println(Sqrt(-2)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"code.google.com/p/go-tour/pic" | |
"image" | |
"image/color" | |
) | |
type Image struct{ | |
w,h int | |
} | |
func (r *Image) Bounds() image.Rectangle { | |
return image.Rect(0, 0, r.w, r.h) | |
} | |
func (r *Image) ColorModel() color.Model { | |
return color.RGBAModel | |
} | |
func (r *Image) At(x, y int) color.Color { | |
return color.RGBA{uint8(x), uint8(y), 255, 255} | |
} | |
func main() { | |
m := &Image{256,256} | |
pic.ShowImage(m) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"os" | |
"strings" | |
"unicode" | |
) | |
type rot13Reader struct { | |
r io.Reader | |
} | |
func (rot *rot13Reader) Read(p []byte) (n int, err error){ | |
n, err = rot.r.Read(p) | |
for i,c := range(p){ | |
if unicode.IsLetter(rune(c)) { | |
base := byte('a') | |
if(unicode.IsUpper(rune(c))) { | |
base = byte('A') | |
} | |
diff := c - base | |
diff = (diff + 13) % 26 | |
p[i] = base + diff | |
} | |
} | |
return n,err | |
} | |
func main() { | |
s := strings.NewReader( | |
"Lbh penpxrq gur pbqr!") | |
r := rot13Reader{s} | |
io.Copy(os.Stdout, &r) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// goをつけてメソッド呼び出しすればスレッドで処理できる | |
package main | |
import ( | |
"fmt" | |
"time" | |
) | |
func say(s string) { | |
for i := 0; i < 5; i++ { | |
time.Sleep(100 * time.Millisecond) | |
fmt.Println(s) | |
} | |
} | |
func main() { | |
go say("world") | |
say("hello") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// スレッド間の通信にはチャンネルを使う | |
// 明示的なロックなどは必要ない | |
package main | |
import "fmt" | |
func sum(a []int, c chan int) { | |
sum := 0 | |
for _, v := range a { | |
sum += v | |
} | |
c <- sum // send sum to c | |
} | |
func main() { | |
a := []int{7, 2, 8, -9, 4, 0} | |
c := make(chan int) | |
go sum(a[:len(a)/2], c) | |
go sum(a[len(a)/2:], c) | |
x, y := <-c, <-c // receive from c | |
fmt.Println(x, y, x+y) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 送信側はclose()で送信の終了を明示的に示せる | |
// 送信の終了は第2パラメータでチェックできる | |
package main | |
import ( | |
"fmt" | |
) | |
func fibonacci(n int, c chan int) { | |
x, y := 0, 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) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Tips: フィボナッチ数の計算は、以下の様に一括でかける | |
// select構文はswitchのgoroutine版? | |
package main | |
import "fmt" | |
func fibonacci(c, quit chan int) { | |
x, y := 0, 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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"code.google.com/p/go-tour/tree" | |
"fmt" | |
) | |
// Walk walks the tree t sending all values | |
// from the tree to the channel ch. | |
func Walk(t *tree.Tree, ch chan int){ | |
if t != nil { | |
_walk(t, ch) | |
} | |
close(ch) | |
} | |
func _walk(t *tree.Tree, ch chan int){ | |
if t == nil { | |
return | |
} | |
// 左から深さ優先で調べていかないと、整合性がとれない | |
_walk(t.Left,ch) | |
ch <- t.Value | |
_walk(t.Right,ch) | |
return | |
} | |
// Same determines whether the trees | |
// t1 and t2 contain the same values. | |
func Same(t1, t2 *tree.Tree) bool{ | |
ch1 := make(chan int) | |
ch2 := make(chan int) | |
go Walk(t1, ch1) | |
go Walk(t2, ch2) | |
for c1 := range ch1 { | |
c2 := <- ch2 | |
if c1 != c2 { | |
return false | |
} | |
} | |
// ch1よりch2の要素が多い場合もエラー | |
if _, ok := <- ch2 ; ok { | |
return false | |
} | |
return true | |
} | |
func main() { | |
/* | |
ch := make(chan int, 10) | |
go Walk(tree.New(1), ch) | |
for i := range ch{ | |
fmt.Println(i) | |
} | |
*/ | |
if test1 := Same(tree.New(1), tree.New(1)) ; test1 == true { | |
fmt.Println("correct!") | |
}else{ | |
fmt.Println("incorrect...") | |
} | |
if test2 := Same(tree.New(1), tree.New(2)) ; test2 == false { | |
fmt.Println("correct!") | |
}else{ | |
fmt.Println("incorrect...") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment