たなしょのメモ

日々勉強していることをつらつらと

Goの学習メモ11

可変長

引数を可変長にすることができるらしい。

package main

import "fmt"

func foo(params ...int) {
    fmt.Println(len(params), params)
    for _, param := range params {
        fmt.Println(param)
    }
}

func main() {
    foo()
    foo(10, 20)
    foo(10, 20, 30)

    s := []int{1, 2, 3}
    fmt.Println(s)

    foo(s...)
}

引数を...intとすると可変長になる。

func foo(params ...int)

可変長の引数に配列などを代入するのも...を使う。

s := []int{1, 2, 3}
fmt.Println(s)
foo(s...)

if

if文内で関数を呼び出して判定させる場合はスコープもif文の中でしかできない。

if result2 := by2(10); result2 == "ok" {
    fmt.Println("great 2")
}

switch

if文と同じでswitch文の中で関数を呼んで判定できる。
それとdefaultを書かなくてもよい。

package main

import (
    "fmt"
    "time"
)

func getOsName() string {
    return "rrrrr"
}

func main() {
    switch os := getOsName(); os {
    case "po":
        fmt.Println("ppp")
    case "win":
        fmt.Println("sss")
    default:
        fmt.Println("ddddd")
    }

    t := time.Now()
    fmt.Println(t.Hour())
    switch {
    case t.Hour() < 12:
        fmt.Println("Mornig")
    case t.Hour() < 17:
        fmt.Println("Afternoon")
    default:
        fmt.Println("night")
    }
}

defer

なんとなく使い方はわかっていたけどこう使うんだということがわかった。
確かにfile Readの際にdeferでfileクローズさせてあげればいいのか。

package main

import (
    "fmt"
    "os"
)

func foo() {
    defer fmt.Println("world foo")

    fmt.Println("hello foo")
}

func main() {
    file, _ := os.Open("./defer.go")
    defer file.Close()
    data := make([]byte, 100)
    file.Read(data)
    fmt.Println(string(data))
}

logging

loggingを学習した。
log.Printf、log.Println、log.Fatalf、log.Fatallnを覚えておけばいいのかな。

package main

import (
    "io"
    "log"
    "os"
)

func LoggingSettings(logFile string) {
    logfile, _ := os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
    multiLogFile := io.MultiWriter(os.Stdout, logfile)
    log.SetFlags(log.Ldate | log.Ltime | log.Llongfile)
    log.SetOutput(multiLogFile)
}

func main() {
    LoggingSettings("test.log")
    _, err := os.Open("dsaf")
    if err != nil {
        log.Fatalln("Exit", err)
    }
}

エラーハンドリング

ファイルオープンの際に使うエラーハンドリングを学習した。
:= は左側の変数が新しければ使えるんだ。

package main

import (
    "fmt"
    "log"
    "os"
)

func main() {
    file, err := os.Open("./err.go")
    if err != nil {
        log.Fatalln("Error!")
    }
    defer file.Close()
    data := make([]byte, 200)
    count, err := file.Read(data)
    if err != nil {
        log.Fatalln("Error")
    }
    fmt.Println(count, string(data))
}

panic&recocer

panicが例外処理でrecoverは起動するとpanic の例外処理が発動しない。

package main

import "fmt"

func thirdPartyConnectDB() {
    panic("Unable to connect database!")
}

func save() {
    defer func() {
        s := recover()
        fmt.Println(s)
    }()
    thirdPartyConnectDB()
}

func main() {
    save()
    fmt.Println("OK?")
}