golangノート——プロセス制御

11384 ワード

じょうけんステートメント
  if ... else if ... else文:
if num > 100{
    fmt.Println(">100")    
} else if 0 < num {
    fmt.Println("<0")
} else {
    fmt.Println("0<<num<<100")
}

 
ループステートメント
GO言語のswitch文は2つに分けられ、1つは式switch文であり、他の言語のswitchの使用方法と同じである.もう1つは、タイプ断言に似ているが、typeキーワードを使用して判断されるタイプとして機能するタイプ判定switch文である.
式switchの例は次のとおりです.
    //  switch
    switch content := getContent(); content {
    default:
        fmt.Println("Unknow language")
    case "Lua":
        break
    case "Python":
        fmt.Println("python")
    case "C", "C++", "Java":
        fmt.Println("A compiled language")
    }

タイプ判定switch文の例は次のとおりです.
    v := "3"
    switch interface{}(v).(type) {
    case string:
        log.Printf("Thie string is '%s'.
", v) case int, uint, int8, uint8, int16, uint16: log.Printf("Thie integer is %d.
", v) default: log.Printf("Unsupported value.(type=%T)
", v) }

さらに、switch文は直列if文の代替案を実現することができ、コードをより明確に読みやすくすることができ、switch式が欠けている場合、switch判定ターゲットはブールタイプと見なされ、trueを返す最初のcase式が実行されます.
    switch {
    case num > 100:
        log.Println(">100")
    case num < 0:
        log.Println("<0")
    default:
        log.Println("0<<num<<100")
    }

for文には3つの使い方があります.1つは通常の使い方で、構造は前後して初期化サブ文、条件、後置サブ文です.例えば:
    sum := 0
    for i := 0; i < 100; i++ {
        sum += i
    }

二つ目は、GO言語にwhileループがないことに注意して、他の言語のwhileのような役割です.
    i := 0
    for i < 100 {
        i += 2
    }

3つ目は、配列や辞書などのタイプを反復するための他の言語のforeachのような役割です.
    m := map[string]int{"A": 1, "B": 2}
    for k, _ := range m {
        log.Print(k)
    }

注意:if/for/switch文は、オプションの初期化サブ文を受け入れることができます.breakcontinuegoto文は、指定したタグにジャンプできます.タグの定義は「識別子:」の形式を使用します.
 
goto文
goto文はタグに合わせてしか実行できず、指定された場所にジャンプします.この文は他の言語で議論されています.一般的にコードの可読性のために使用することは推奨されません.
 
defer文
GO言語特有のプロセス制御文で、1つの関数の呼び出しを予約します.1つの関数(A関数と仮定)にのみ表示され、別の関数(B関数と仮定)のみが呼び出されます.これは、A関数が終了して戻ってくると、ファイルを開くときのリソースクリーンアップなどの作業に使用されるB関数の呼び出しが遅延することを意味します.1つの関数内で複数のdefer文が呼び出される場合、後進先出の原則に従います.defer文の後に匿名関数を付けることで、一時的な機能を迅速に実現できます.defer呼び出しの関数で使用できる変数は、パラメータによって伝達されてもよいし、コンテキストで呼び出されてもよい変数であってもよいし、伝達されていれば直ちに評価され、コンテキストの変数であれば直ちに評価されず、defer関数呼び出し時の値をとる点に注意してください.
 
例外処理文
システムはerrorインタフェースを提供し、以下のように定義されています.
type error interface {
       Error() string    
}

GOではerrorタイプの値を使用して異常な状態を示すことに慣れているが、errorインタフェースを実現するタイプを自分で作成する必要はなく、errorsパッケージから提供される新しい方法で作成する必要がある.例えば、errors.New("this is error"); errorsのソースコードを見てみましょう.
package errors

func New(text string) error {
    return &errorString{text}
}

type errorString struct {
    s string
}

func (e *errorString) Error() string {
    return e.s
}

errorタイプの値をfmtに直接渡すことができる.Printメソッドパラメータは、errorタイプ値のError()メソッドを自動的に検出して出力します.
errosを使う以外はNewメソッドはerrorタイプ値を作成するほか、fmtを使用することもできます.Errorf関数は、フォーマット文字列形式のerrorタイプ値を作成するのに適しており、この方法では画面に出力されないことに注意し、内部ではerrorsが呼び出される.Newが実現したのは、次のようなものです.
err := fmt.Errorf("%s
", "nil error!")

上記の2つのerrorタイプの値を簡単に作成する方法に加えて、osなどのerrorインタフェースを実装する方法をカスタマイズすることで作成することもできる.PathErrorはerrorインタフェースの実装タイプである.OS/errorを表示goのソースコード:
type PathError struct {
    Op   string
    Path string
    Err  error
}

func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }

リカバリ不可能なエラー状態に遭遇した場合、panicとrecoverを使用して例外を処理します.この例外は他の言語の例外に似ていますが、errorは相対的にステータスコードとしか言えません.
panicは任意のタイプの関数(通常stringまたはerrorタイプ)を受け入れ、現在の制御フローを停止し、呼び出された関数に制御権を渡すが、呼び出された関数の実行も停止し、上へ伝播し続ける.GO言語ではrecoverを使用してこのような異常をキャプチャし、現在のプログラムを異常状態から復元してプロセス制御権を再取得し、interface{}タイプを返すことができます.通常、我々はdefer文で匿名の関数を呼び出してrecover処理を行う(異常時にはプロセスが制御不能であるが、GOはdefer文が実行されることを保証するため)、recover()によって現在の異常を取得することができ、nilでなければ異常が存在し、この異常がGO言語実行時プログラムによって引き起こされた場合、runtimeを返す.Errorタイプの値.次のようになります.
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("Recoverd panic:%s
", r) } }()

1つの関数に複数のdefer文がある場合は、その実行順序が先進的な後出の原則に従うことに注意してください.