Go
golang
A_Tour_of_Go
Tech DoDay 18

A Tour of Goの問題を少し解いてみる


Go

業務でGoをやることとなりそうだ、勉強しなくては。。。

ということでGoの入門として、A Tour of Goやっていきます。

image.png


演習問題をひたすら解いていく


Exercise: Loops and Functions


  • 引数の平方根に近い値を返却する

平方根を求めるためのループ回数は10回固定


  • 引数の平方根に一致した時の値とループ回数を返却する

package main

import (
"fmt"
"math"
)

func Sqrt(x float64) float64 {
z := 1.0
for i := 0; i < 10; i++ {
z -= (z * z - x) / (2 * z)
}
return z
}

func SqrtCount(x float64) (float64, int) {
z := 1.0
sqrt := math.Sqrt(x)
count := 0
for ; z != sqrt; count++ {
z -= (z * z - x) / (2 * z)
}
return z, count
}

func main() {
fmt.Printf("Sqrt : %v\n", Sqrt(2))
fmt.Printf("math.Sqrt : %v\n", math.Sqrt(2))
value, count := SqrtCount(2)
fmt.Printf("SqrtCount : %v(%d回ループ)\n", value, count)
}

実行結果

Sqrt : 1.414213562373095

math.Sqrt : 1.4142135623730951
SqrtCount : 1.4142135623730951(5回ループ)


Exercise: Maps

stringで渡される文の、各単語の出現回数を数える

package main

import (
"golang.org/x/tour/wc"
"strings"
)

func WordCount(s string) map[string]int {
count := make(map[string]int)
for _, word := range strings.Fields(s) {
count[word]++
}
return count
}

func main() {
wc.Test(WordCount)
}

実行結果

PASS

f("I am learning Go!") =
map[string]int{"Go!":1, "I":1, "am":1, "learning":1}
PASS
f("The quick brown fox jumped over the lazy dog.") =
map[string]int{"quick":1, "brown":1, "jumped":1, "the":1, "The":1, "over":1, "lazy":1, "dog.":1, "fox":1}
PASS
f("I ate a donut. Then I ate another donut.") =
map[string]int{"another":1, "I":2, "ate":2, "a":1, "donut.":2, "Then":1}
PASS
f("A man a plan a canal panama.") =
map[string]int{"A":1, "man":1, "a":2, "plan":1, "canal":1, "panama.":1}


Exercise: Fibonacci closure

フィボナッチ数を返却するクロージャを返す



package main

import "fmt"

func fibonacci() func() int {
a,b,c := 0,0,1
return func () int {
a, b, c = b, c, b + c
return a
}
}

func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}

実行結果

0

1
1
2
3
5
8
13
21
34


Exercise: Stringers

IPAddr型を実装して、IPアドレスを出力する時の表記を作成する

package main

import "fmt"

type IPAddr [4]byte

func (i IPAddr) String() string {
return fmt.Sprintf("%d.%d.%d.%d", i[0], i[1], i[2], i[3])
}

func main() {
hosts := map[string]IPAddr {
"loopback" : {127, 0, 0, 1},
"googleDNS" : {8, 8, 8, 8},
}
for name, ip := range hosts {
fmt.Printf("%v: %v\n", name, ip)
}
}

出力結果

loopback: 127.0.0.1

googleDNS: 8.8.8.8


Exercise: rot13Reader

ROT13換字式暗号を変換する

package main

import (
"io"
"os"
"strings"
)

type rot13Reader struct {
r io.Reader
}

func (rot rot13Reader) Read (b []byte) (int, error) {
num, err := rot.r.Read(b)

if err != nil {
return num, err
}

for i := 0; i < num; i++ {
if ('a' <= b[i] && b[i] <= 'm') || ('A' <= b[i] && b[i] <= 'M'){
b[i] += 13
} else if ('n' <= b[i] && b[i] <= 'z') || ('N' <= b[i] && b[i] <= 'Z') {
b[i] -= 13
}
}
return num, err
}

func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}

出力結果

You cracked the code!


所感


  • 書いていてポインタがあったり、複数の値を返却できたりと書きやすいところが多い。

  • goroutine, channelがあって並列処理とかも楽に書けそう。

  • 調べる限りだとコンパイルが速いと書いてあったが、そこまで速さが実感できなかった。(他PCで見せてもらった時は速かったので実行環境が悪いだけだと思うが。。。)

image.png