9

len(p) は何回実行されますか? 1 つだけで結果が保存されますか、それとも反復ごとに実行されますか?

func main() {
    p := []int{2, 3, 5, 7, 11, 13}
    for i:=0;i<len(p);i++ {}
}
4

4 に答える 4

12

len()スライス上では、コンパイラによって最適化されます。これは、ローカル変数にアクセスするようなものです。これは実際には関数呼び出しではありません。

次の方法で確認できます。

$ cat x.go
パッケージメイン
「fmt」をインポート
関数メイン() {
    a := []int{1,2, 3}
    fmt.Println(len(a))
}

次に、コンパイラの出力を見てください。

$ go ツール 6g -S x.go

--- プログラム一覧「メイン」 ---
0000 (x.go:3) TEXT メイン+0(SB),$128-0
0001 (x.go:4) MOVQ $0,autotmp_0002+-80(SP)
0002 (x.go:4) MOVQ $0,autotmp_0002+-72(SP)
0003 (x.go:4) MOVQ $0,autotmp_0002+-64(SP)
0004 (x.go:4) LEAQ autotmp_0002+-80(SP),BX
0005 (x.go:4) MOVQ BX,autotmp_0001+-56(SP)
0006 (x.go:4) MOVQ autotmp_0001+-56(SP),BX
0007 (x.go:4) MOVQ statictmp_0000+0(SB),BP
0008 (x.go:4) MOVQ BP,(BX)
0009 (x.go:4) MOVQ statictmp_0000+8(SB),BP
0010 (x.go:4) MOVQ BP,8(BX)
0011 (x.go:4) MOVQ statictmp_0000+16(SB),BP
0012 (x.go:4) MOVQ BP,16(BX)
0013 (x.go:4) MOVQ autotmp_0001+-56(SP),BX
0014 (x.go:4) MOVQ $3,CX
0015 (x.go:5) LEAQ autotmp_0005+-16(SP),DI
0016 (x.go:5) MOVQ $0,AX
0017 (x.go:5) STOSQ 、
0018 (x.go:5) STOSQ 、
0019 (x.go:5) LEAQ autotmp_0005+-16(SP),BX
0020 (x.go:5) MOVQ BX,autotmp_0004+-48(SP)
0021 (x.go:5) MOVQ autotmp_0004+-48(SP),BX
0022 (x.go:5) MOVQ $1,SI
0023 (x.go:5) MOVQ $1,DX
0024 (x.go:5) MOVQ BX,autotmp_0003+-40(SP)
0025 (x.go:5) MOVQ autotmp_0003+-40(SP),BX
0026 (x.go:5) MOVQ $type.int+0(SB),AX
0027 (x.go:5) MOVQ AX、(BX)
0028 (x.go:5) MOVQ CX,8(BX)
0029 (x.go:5) MOVQ autotmp_0003+-40(SP),BX
0030 (x.go:5) MOVQ BX,(SP)
0031 (x.go:5) MOVQ SI,8(SP)
0032 (x.go:5) MOVQ DX,16(SP)
0033 (x.go:5) CALL ,fmt.Println+0(SB)
0034 (x.go:6) RET 、

への呼び出しがあることに注意してください。fmt.Printlnただし、への呼び出しはありませんlen

于 2013-02-02T16:32:35.687 に答える
9

実験してみよう! http://play.golang.org/p/Eksb6bQovC

または、次のドキュメントを参照してください: http://golang.org/ref/spec#For_statements (TL;DR: 「条件は各反復の前に評価されます。」)

あなたの例では、 len は条件の一部であるため、各反復の前に評価されます。条件が true と評価される 6 回の反復があり、次に false と評価されるもう 1 つの評価が行われ、for ループが終了します。ということで、全部で7回。

于 2013-02-02T14:09:30.740 に答える
2

2 番目の実験:

func Test_X(t * testing.T) {
    list := []int{1, 2, 3}
    fmt.Printf("# b: len(list) %d\n", len(list))
    for i := 0; i < len(list); i++ {
        fmt.Printf("# %d: len(list) %d, list[%d] == %d\n", i, len(list), i, list[i])
        if i == 2 {
            list = append(list, 4)
        }
    }
    fmt.Printf("# a: len(list) %d\n", len(list))
}

出力:

=== RUN Test_X
# b: len(list) 3
# 0: len(list) 3, list[0] == 1
# 1: len(list) 3, list[1] == 2
# 2: len(list) 3, list[2] == 3
# 3: len(list) 4, list[3] == 4
# a: len(list) 4
--- PASS: Test_X (0.05 seconds)

len() 呼び出しを最適化しない理由を示します。

于 2013-02-02T14:45:14.127 に答える
-4

アルゴリズムの観点から、条件は for ループの各ステップで評価されます。この場合、len(p) の評価の 6 倍になるようです。

于 2013-02-02T13:44:53.653 に答える