0
0

More than 1 year has passed since last update.

Goアウトプット #03 【関数】

Posted at

関数

  • Go言語の関数は複数の値を返すことができる
  • 関数の中には名称のない匿名関数を作成することができる
  • main()関数(エントリーポイント)
    └引数、戻り値を返さない
    └基本的にプロジェクトに1つで、パッケージはmainになる
  • funcキーワードで開始し、関数名、引数(省略可)、戻り値(省略可)を宣言

基本的な関数の文法

func main() {
    result := pls(10, 10)
    fmt.Printf("result=%d \n", result)
}

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

// -> result=20

多値を返す関数

  • Go言語は関数の戻り値を多値で返すことができる

戻り値の文法(戻り値の型指定のみ)

func 関数名(引数名 [, .....])(戻り値の型[, ....]){
    処理
    return 戻り値
}
func main() {
    add, sub := calc(10, 20)
    fmt.Println(add, sub)
}

func calc(x int, y int) (int, int) {
    add := x + y
    sub := x - y
    return add, sub
}

// -> 30 -10

戻り値の文法(戻り値を変数に代入する)

  • 「名前付き戻り値」ともいう。
func 関数名(引数名 [, .....])(戻り値の変数名 戻り値の型[, ....]){
    処理
    return 戻り値
}
func main() {
    add, sub := calc(10, 20)
    fmt.Println(add, sub)
}

func calc(x int, y int) (add int, sub int) {
    add = x + y
    sub = x - y
    return
}

// -> 30 -10

可変長引数

  • 引数の型名の前に...を入れると、一度に複数の値を渡すことができる。
    └関数呼び出し時に暗黙的なスライスが作成される。
func 関数名(引数名...){
    処理
}
func main() {
    sum := CalcSum(100, 200, 300, 400)
    avg := CalcAvg(100, 200, 300, 400)
    fmt.Printf("sum=%d, avg=%d \n", sum, avg)
}

func CalcSum(values ...int) (sum int) {
    for _, value := range values {
        sum += value
    }
    return
}

func CalcAvg(values ...int) (avg int) {
    for _, value := range values {
        avg += value
    }
    avg = avg / cap(values)
    return
}

// -> sum=1000, avg=250

匿名関数(関数リテラル)

  • 関数やメソッド内に作成した関数で、名称を持たない
    └すぐに呼び出す場合は、関数の最後に()をつける。

変数に代入して利用する場合

func main() {
    // 引数の値を表示する匿名関数を変数functionに代入する
    function := func(result int) {
        // 引数として受け取った加算結果を出力する
        fmt.Printf("答え=%d \n", result)
    }
    // 加算結果を匿名関数の引数として入力する
    function(100 + 200)
}

// -> 答え=300

直ぐに呼び出す場合

※遅延実行で使用する(defer)

func main() {
    // 引数の値を表示する匿名関数を直ぐに実行する
    func(result int) {
        fmt.Printf("答え=%d \n", result)
    }(100 + 200)
}

関数型

  • 関数を変数に代入するときに使用する
// 加算と減算を戻り値として返す関数
func CalcA(x int, y int) (int, int) {
    add := x + y
    sub := x - y
    return add, sub
}

// 多値の合計を戻り値として返す関数
func CalcSum(values ...int) (sum int) {
    for _, value := range values {
        sum += value
    }
    return
}

// 関数型の宣言
type CalcFuncType1 func(int, int) (int, int)
type CalcFuncType2 func(...int) int

func main() {
    var func1 CalcFuncType1 = CalcA
    add, sub := func1(10, 20)
    fmt.Printf("add=%d, sub=%d \n", add, sub)

    // 別の変数を使用すれば、同じ関数型を使用することができる
    var func2 CalcFuncType1 = CalcA
    add, sub = func2(20, 30)
    fmt.Printf("add=%d, sub=%d \n", add, sub)

    var func3 CalcFuncType2 = CalcSum
    sum := func3(100, 200, 300, 400)
    fmt.Printf("sum=%d \n", sum)
}

// -> add=30, sub=-10 
//    add=50, sub=-10 
//    sum=1000

遅延実行

  • 関数呼び出しにキーワードdeferをつけると、遅延実行することができる。
    └遅延実行は、deferを記述した関数の処理が全て終わったときに実行される
    └パニックが発生しても遅延実行の関数は必ず実行される
    └関数内喉の場所に記述しても、最後に実行される
    └ループ処理内で遅延実行されると、実行を置いておくことができ、LIFO形式で実行される
func Message(msg string) {
    fmt.Println(msg)
}

func main() {
    defer Message("message1")
    fmt.Println("実行")
    defer Message("message2")
}
// LIFO形式で実行される

// -> 実行
//    message2
//    message1

ループ内で実行

func message(msg string) {
    fmt.Println(msg)
}

func main() {
    for i := 0; i < 5; i++ {
        fmt.Println("実行 i=", i)
        defer message(fmt.Sprintf("メッセージ%d", i))
    }
}

// -> 実行 i= 0
//    実行 i= 1
//    実行 i= 2
//    実行 i= 3
//    実行 i= 4
//    メッセージ4
//    メッセージ3
//    メッセージ2
//    メッセージ1
//    メッセージ0
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0