👋
A Tour of Go
Go言語のツアー
Goのツアーやってたら課題が出てきたので、回答を残しとく
(Exercise: Loops and Functions)
package main
import (
"fmt"
"math"
)
// Exercise: Loops and Functions
func Sqrt(x float64) float64 {
z := 1.0
for i := 1; i <= 10; i++ {
// ループは最大10回
// ニュートン法の計算式
z -= (z*z - x) / (2 * z)
fmt.Println("Loop Count i=", i, "Calculation =", z)
if math.Sqrt(x) == z {
// ライブラリで変数xの平方根を計算し一致したらループ終了
fmt.Println("Calculation has completed.")
break
}
}
return z
}
func main() {
var target = 2.0
calcvalue := Sqrt(target)
libvalue := math.Sqrt(target)
diff := calcvalue - libvalue
fmt.Println("My Function Result=", calcvalue)
fmt.Println("Library Result=", libvalue)
fmt.Println("Diff", diff)
}
- 振り返り
- 問題文から要件を理解するのが一番時間かかったかも。
- breakの条件でmath.Sqrt(x) == zとしたが、左辺はループの外に定義するか迷った
(Exercise: Slices)
package main
import (
//"fmt"
"golang.org/x/tour/pic"
)
func Pic(dx, dy int) [][]uint8 {
// 親配列の長さ:dy :
// 小配列の長さ:dx :
sdy := make([][]uint8, dy)
for i := range sdy {
sdy[i] = make([]uint8, dx)
for j := range sdy[i] {
sdy[i][j] = uint8((i+j)/2)
}
}
return sdy
}
func main() {
//fmt.Println("main start")
pic.Show(Pic)
}
- 振り返り
- varか:=か迷った。:=に寄せるほうが一般的らしい。
- 未使用のインポートはエラーになるのが鬱陶しい。
- print使ったら画像が表示されなかった。出力の根っこのところがそういう感じなんだろーなーで留めた。
(Exercise: Maps)
package main
import (
"golang.org/x/tour/wc"
"strings"
)
func WordCount(s string) map[string]int {
words := strings.Fields(s)
wordCountMap := make(map[string]int)
count := 0
for _, target := range words {
for _, val := range words {
if target == val {
count++
}
}
wordCountMap[target] = count
count = 0
}
return wordCountMap
}
func main() {
wc.Test(WordCount)
}
-
振り返り
- テスト駆動ってこういうのなのかな。最初何していいのかわからなかった。
- 配列を検索する機能が標準でありそうだがみつからず。泥臭く実装した
-
レビューバック
- 2回もループするなよ、と。修正してスッキリしたし処理回数も少なくなった。
package main
import (
"golang.org/x/tour/wc"
"strings"
)
func WordCount(s string) map[string]int {
words := strings.Fields(s)
wordCountMap := make(map[string]int)
for _, target := range words {
// ここを修正した
wordCountMap[target] = wordCountMap[target] + 1
}
return wordCountMap
}
func main() {
wc.Test(WordCount)
}
(Exercise: Fibonacci closure)
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
// フィボナッチ数列を格納する配列
fibonaccilist := [] int{0,1}
// 実行回数
count := 0
// (n + n-1)番目を格納する変数
sum := 0
return func() int {
// (n+1 + n)番目を計算
sum = fibonaccilist[count] + fibonaccilist[count+1]
fibonaccilist = append(fibonaccilist,sum)
// 実行回数インクリメント
count++
return fibonaccilist[count-1]
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
- 振り返り
- どこを軸(配列の添字)にしてるのか、書いてて混乱した。
- もう少しスッキリ書けないのか
- レビューバック
- 配列使わなくていい。そしてもっとスッキリ書ける。
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
f0 := 0
f1 := 1
return func() int {
// n+2番目を計算
f2 := f0 + f1
// n番目を返却する変数に退避
x := f0
// n+1番目をn番目に設定
f0 = f1
// n+2番目をn+1番目に設定
f1 = f2
return x
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
- 振り返り
- 最低限の変数のみでスッキリ。何度実行してもメモリ使用量が一定なのがミソ。
(Exercise: Stringers)
package main
import "fmt"
type IPAddr [4]byte
// TODO: Add a "String() string" method to IPAddr.
func (ip IPAddr) String() string {
return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[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)
}
}
- 振り返り
- ポインター型にするとカンマが消える。なんで?(めも)
- IPAddrがポインタ型ではない為
- ポインター型にするとカンマが消える。なんで?(めも)
(Exercise: Errors)
package main
import (
"fmt"
"math"
)
type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string {
v := fmt.Sprint(float64(e))
return fmt.Sprintf("cannot Sqrt negative number: %v", v)
}
func Sqrt(x float64) (float64, error) {
z := 1.0
var y float64
if x < 0 {
return x, ErrNegativeSqrt(x)
}
for i := 1; i <= 10; i++ {
// ループは最大10回
// 計算式
y = (z*z - x) / (2 * z)
z -= y
fmt.Println("Loop Count i=", i, "Calculation =", z)
if math.Sqrt(x) == z {
// ライブラリと一致したらループ終了
fmt.Println("Calculation has completed.")
break
}
}
return z, nil
}
func main() {
fmt.Println(Sqrt(2.0))
fmt.Println(Sqrt(-2))
}
(Exercise: Readers)
package main
import "golang.org/x/tour/reader"
type MyReader struct{}
// TODO: Add a Read([]byte) (int, error) method to MyReader.
func (r MyReader) Read(b []byte) (int, error) {
for i, _ := range b {
b[i] = 'A'
}
return len(b), nil
}
func main() {
reader.Validate(MyReader{})
}
Discussion