JavaScriptを有効にしてください

The tour of go をやって大事だと思ったとこだけメモ

 ·  ☕ 7 分で読めます  ·  ✍️ saiki

またtour of goをやったのでその中で覚えとこうと思ったとこだけメモりました。

本当にメモなので雑ですが。

いつのまにか全部日本語になっていて嬉しかったです。

目次

関数の引数は型が同じならまとめられる

func add(x, y int) int {
    return x + y
}

関数は複数の戻り値を返せる

戻り値に名前をつけられる.宣言までしてくれる(慣れるまで読みづらそう)

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

var は:で省略できる

var a = 2
a := 2

func main() {
    var i int
    var f float64
    var b bool
    var s string
    fmt.Printf("%v %v %v %q", i, f, b, s)
}

型変換は明示的にしなければならない

キャストしないとエラーになる

i := 42
f := float64(i)
u := uint(f)

constはnumeric 謎

forとifに()いらない

switch基本breakされる。したくなければfallthroughをcaseの最後につける

swichに条件式かける

deferはreturnの後に関数を呼ぶように予約することができる

defer へ渡した関数の引数は、すぐに評価されますが、その関数自体は呼び出し元の関数がreturnするまで実行されません。

複数deferはLIFO(last-in-first-out:最後に入れたのが最初に出る)で実行される

&がポインタへのキャスト が値へのキャスト と覚える。型宣言の時はintとなるので注意

配列

primes := [6]int{2, 3, 5, 7, 11, 13}
ve]

===========Slice始まり============

[]に長さ指定しなければSliceになる

var s []int = 配列[1:4]

sliceは配列への参照のようなもの

sliceを直接作ると配列を作ってからそれを参照するスライスを作成するようになっている

sliceを作る時配列全部入れたいならa[:]がいいかな

//以下の配列において
var a [10]int

//これらのスライス式は等価です:
a[0:10]
a[:10]
a[0:]
a[:]

len(slice)が長さ。cap(slice)はsliceの最初の要素から元となる配列の末尾までの長さ

slice nilでもlenとcapに0入る

ていうかnullじゃなくてnilなのか

makeでSliceの初期化

b := make([]int, 0, 5) // len(b)=0, cap(b)=5

SliceのSliceとかも作れる(二次元配列的な)

Sliceに要素をたすにはappend(slice,要素)

cap超えたら倍の配列を割り当て直す(Listと同じだね)
nilのsliceにも追加できる

===========slice終わり============

Range

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range pow {
    fmt.Printf("2**%d = %d\n", i, v)
}
//iはインデックスvは要素のコピー

===========mapはじまり============

mapはDictionaryみたいなもん

tryGetしなくてもバグらない

v, ok := m["Answer"]

===========map終わり============

closureよくわかんねえけど気をつけよう

type hoge int で型を宣言できる。それにメソッドを持たせることもできる。

同じパッケージで宣言されている型にしかメソッド宣言できない。そりゃそうだ

goは常に値渡し

メソッドのレシーバーはポインタと型(?)で指定できる。インスタンスの内容を変更する場合はポインタじゃないとどうにもならない

メソッド基本的にポインタレシーバで宣言する!!

interfaceは明示的にimplementsしないでメソッドを実装しさえすればimplementsしてるとみなされる

interfaceのメソッドをポインタレシーバで実装したら参照を使わないとエラー出る。。。引っかかりそう

空のinterface{}はObjectみたいなもの

Type assertions 多分isからのasみたいなもん

var i interface{} = "hello"
s,ok := i.(string)
fmt.Println(s)

swichを使うと複数いける。あんま使って欲しくなさそう

switch v := i.(type) {
case T:
    // here v has type T
case S:
    // here v has type S
default:
    // no match; here v has the same type as i
}

Stringersインターフェース String()メソッドを実装するとstringとして出力できる?

Error() stringを実装すればerrorとして扱える

Channels

ch := make(chan int)
//みたいに宣言 chan int で多分型なので注意(初見だと読みづらい)

//こう使う
ch <- v    // v をチャネル ch へ送信する
v := <-ch  // ch から受信した変数を v へ割り当てる

//イメージ的にはキューにgoroutineを詰めてる感じ
//ch <-で詰めたgoroutineが全て終わらなければ <-ch は呼ばれない
//詰めたより多く<-chするとエラーが出る

バッファとしてもよく使いそうだな〜しんどい

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 しないとmain()のforで一生回るのでnull的なエラーが出る
    close(c)
}

func main() {
    c := make(chan int, 10)
    go fibonacci(cap(c), c)
    for i := range c {
        fmt.Println(i)
    }
}

Select

これは便利だ〜
channelが準備できるまで待って準備できたのから実行してくれる。複数準備できてたらランダム実行

package main

import "fmt"
import "time"


func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
    time.Sleep(1 * time.Second) // 1秒待つ
        select {
        case c <- x:
            fmt.Println("case c")
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)

    go func() {
        fmt.Println("func")
        for i := 0; i < 10; i++ {
            fmt.Println("funcの方",<-c)
        }
        quit <- 0
    }()
    fmt.Println("fibo前")
    fibonacci(c, quit)
}

こういう使い方もできるticktとafterhはchを返すんだね

package main

import (
    "fmt"
    "time"
)

func main() {
    tick := time.Tick(100 * time.Millisecond)
    boom := time.After(500 * time.Millisecond)
    for {
        select {
        case <-tick:
            fmt.Println("tick.%T",tick)
        case <-boom:
            fmt.Println("BOOM!")
            return
        default:
            fmt.Println("    .")
            time.Sleep(50 * time.Millisecond)
        }
    }
}

sync.Mutex

Lock して居るうちは他からアクセスできない

 

 

そのうち気が向けば綺麗にまとめたいね。

それにしてもgoroutineとかselectとかchannelとかは使いようによってはものすごく便利そうですね。

素敵。ではまた。

共有

saiki
著者
saiki
Android App Developper