9

私は次のコードを書きました。しかし、私はそれをコンパイルさせることはできません。これが私のコードです:

package main

import "fmt"

func main() {
    tmp := make([]int, 10)
    for i := 0; i < 10; i++ {
        tmp[i] = i
    }
    res := mapx(foo, tmp)
    fmt.Printf("%v\n", res)
}

func foo(a int) int {
    return a + 10
}

func mapx(functionx func(int) int, list []int) (res []int) {
    res = make([]int, 10)
    for _, i := range(list) {
        append(res, functionx(i))
    }
    return
}

一方、エラーメッセージも非常に紛らわしいです。 prog.go:21: append(res, functionx(i)) not used

append(res, functionx(i))しかし、 (21行目)をに置き換えるとres = append(res, functionx(i))、非常にうまく機能します。誰か助けてもらえますか?

ありがとうございました!

4

1 に答える 1

30

スライスへの追加とコピー

可変引数関数 append は、スライス型でなければならない S 型の s に 0 個以上の値 x を追加し、これも S 型の結果のスライスを返します。

s の容量が追加の値に適合するほど大きくない場合、append は、既存のスライス要素と追加の値の両方に適合する、十分に大きな新しいスライスを割り当てます。したがって、返されたスライスは別の基になる配列を参照する場合があります。

通話

関数呼び出しでは、関数の値と引数は通常の順序で評価されます。それらが評価された後、呼び出しのパラメーターは値によって関数に渡され、呼び出された関数が実行を開始します。関数の戻りパラメーターは、関数が戻るときに、呼び出し元の関数に値で渡されます。

Go では、引数は値渡しです。

res = append(res, functionx(i))res の新しい値を破棄しないように記述する必要があります。これは、別のスライスと、場合によっては別の基になる配列を参照します。

例えば、

package main

import "fmt"

func main() {
    res := []int{0, 1}
    fmt.Println(res)
    _ = append(res, 2) // discard
    fmt.Println(res)
    res = append(res, 2) // keep
    fmt.Println(res)
}

出力:

[0 1]
[0 1]
[0 1 2]
于 2012-05-24T15:20:52.647 に答える