NOGU.D

どっかの大学の学部生のメモ程度の記事

Golang プログラムを終了

os.Exit()

os.Exitを使うとdeferは実行されない。


package main

import (
    "fmt"
    "os"
)

func main() {

    fmt.Println("!")

    os.Exit(3)
}
func Exit(code int) Exit causes the current program to exit with the given status code. Conventionally, code zero indicates success, non-zero an error. The program terminates immediately; deferred functions are not run.

ドキュメントにはdeferに登録した関数をすべて破棄すると書かれている。

main関数でdefer文と併用してos#Exit関数を実行すると意図しない挙動をする可能性がある。また、「immediately」なので他のゴルーチンの終了などは待機しない。


$ go build main.go
$ ./main
$ echo $?
3
バイナリをビルドしてから実行する場合は、ターミナル上でステータスを確認することが可能。

参考

Golangのflagパッケージ

基本的な使い方

パッケージをインポート


import "flag"

フラグの値を格納する変数を定義

flag.String(), Bool(), Int() などを使用してフラグを定義。 フラグを格納するための変数にポインタを返す。

flag.XXXX( <パラメータ名>, <デフォルト値>, <パラメータの説明>)

boolPtr := flag.Bool("b", false, "真偽値の値の例") 
intPtr := flag.Int("i", 0, "数値の場合の例") 
strPtr := flag.String("s", "", "文字列の場合の例")

フラグの解析と取得

flag.Parse()を呼ぶことでコマンドラインの引数のフラグが解析され、フラグが変数にバインドされる。


flag.Parse()

フラグの解析と取得

実際のオプション値を取得するために、*変数名 のようにポインタをデリファレンスする必要がある点に気をつけてください。


fmt.Println(*boolPtr)
fmt.Println(*intPtr)
fmt.Println(*strPtr)

全体のソースコード


package main

import (
  "flag"
  "fmt"
)

func main() {
  boolPtr := flag.Bool("b", false, "真偽値の値の例")
  intPtr := flag.Int("i", 0, "数値の場合の例")
  strPtr := flag.String("s", "", "文字列の場合の例")

  flag.Parse()

  fmt.Println(*boolPtr)
  fmt.Println(*intPtr)
  fmt.Println(*strPtr)
}

ヘルプを表示する

<コマンド> -h または コマンド -help を実行するとコマンドのヘルプ(Usage)が表示されます

実際に以上のサンプルコードを使って実行した結果


% go run main.go -help
Usage of /var/folders/l0/tj5zqgc916vdp_k4wtv4wmd80000gw/T/go-build2703247103/b001/exe/main:
  -b	真偽値の値の例
  -i int
    	数値の場合の例
  -s string
    	文字列の場合の例

その他

サンプル1


package main

import (
    "flag"
    "fmt"
)

func main() {
    var (
        msg   = flag.String("String", "default message.", "is String")
        num   = flag.Uint("Number", 0, "is Nuber")
        debug = flag.Bool("Boolean", false, "True or False")
    )

    flag.Parse()

    fmt.Printf("param -m -> %s\n", *msg)
    fmt.Printf("param -n -> %d\n", *num)
    fmt.Printf("param -debug -> %t\n", *debug)
}

サンプル2


package main

import (
    "flag"
    "fmt"
)

func main() {
    var (
        msg   string
        num   uint
        debug bool
    )

    flag.StringVar(&msg, "m", "default message.", "is String")
    flag.UintVar(&num, "n", 0, "is Nuber")
    flag.BoolVar(&debug, "debug", false, "True or False")

    flag.Parse()

    fmt.Printf("param -m -> %s\n", msg)
    fmt.Printf("param -n -> %d\n", num)
    fmt.Printf("param -debug -> %t\n", debug)
}

参考

Golang(関数)

関数の定義

GolangではPublicとPrivateと言うキーワードは存在しないが、大文字と小文字でPublic関数とPirvate関数を判別する。Public関数は他のパッケージで当該関数を使うことができますが、Private関数は当該パッケージ内のみで使うことが可能。


package main

import "fmt"

func p(i interface{}) {
    fmt.Println(i)
}

func main() {
    p("It's sample function")
    p("Everything is fiction.")
}

上記は、渡された文字列を標準出力をするだけのシンプルな関数

PublicとPrivate

GolangではPublicとPrivateと言うキーワードは存在しないが、大文字と小文字でPublic関数とPirvate関数を判別する。Public関数は他のパッケージで当該関数を使うことができますが、Private関数は当該パッケージ内のみで使うことが可能。

  • 関数名が大文字で始まる: Public関数
  • 関数名が小文字で始まる: Private関数
関数の後ろに戻り値の型を定義することで、値を返却できる様になる。

func 関数名 (引数 型) 型 {
    // do something
    return 値
}
複数の値を返却する時ときはこのように定義する。

func 関数名 (引数 型) (型, 型) {
    // do something
    return 値, 値
}