len(p) 会运行多少次?只有一个,结果将被保存,还是每次迭代都会运行?
func main() {
p := []int{2, 3, 5, 7, 11, 13}
for i:=0;i<len(p);i++ {}
}
len(p) 会运行多少次?只有一个,结果将被保存,还是每次迭代都会运行?
func main() {
p := []int{2, 3, 5, 7, 11, 13}
for i:=0;i<len(p);i++ {}
}
len()
在切片上由编译器优化,就像访问局部变量一样。这不是真正的函数调用。
您可以通过以下方式进行验证:
$ 猫 x.go 包主 导入“fmt” 功能主要(){ a := []int{1,2, 3} fmt.Println(len(a)) }
然后查看编译器输出:
$ go tool 6g -S x.go
--- prog list "main" --- 0000 (x.go:3) 文本主+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) 调用,fmt.Println+0(SB) 0034 (x.go:6) 回复 ,
注意 CALL 到fmt.Println
,但没有调用到len
。
尝试一个实验! http://play.golang.org/p/Eksb6bQovC
或阅读文档: http: //golang.org/ref/spec#For_statements (TL;DR:“在每次迭代之前评估条件。”)
在您的示例中, len 是条件的一部分,因此在每次迭代之前都会对其进行评估。条件评估为真的六次迭代将进行一次迭代,然后再进行一次评估,条件评估为假并退出 for 循环。所以,总共七次。
第二个实验:
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() 调用的原因。
从算法的角度来看,条件是针对循环的每个步骤进行评估的。在这种情况下,它似乎是 len(p) 评估的六倍。