有没有一种方法可以迭代整数范围?

huangapple go评论92阅读模式
英文:

Is there a way to iterate over a range of integers?

问题

Go的range可以遍历映射和切片,但我想知道是否有一种方法可以遍历一系列数字,就像这样:

for i := range [1..10] {
    fmt.Println(i)
}

或者是否有一种表示整数范围的方法,类似于Ruby中的class Range

英文:

Go's range can iterate over maps and slices, but I was wondering if there is a way to iterate over a range of numbers, something like this:

for i := range [1..10] {
	fmt.Println(i)
}

Or is there a way to represent range of integers in Go like how Ruby does with the class Range?

答案1

得分: 369

在Go语言中,惯用的做法是像这样编写for循环:

for i := 1; i <= 10; i++ {
    fmt.Println(i)
}

在范围方面确实有一些优势,并且它们在许多其他语言中被使用,但Go的设计原则是只有在收益明显大于成本(包括使语言变得更复杂的成本)时才引入抽象。对于范围的成本和收益,不同的人可能有不同的看法,但这个答案是我试图描述我认为符合Go语言惯例的方式。

英文:

The idiomatic approach in Go is to write a for loop like this.

for i := 1; i &lt;= 10; i++ {
    fmt.Println(i)
}

There's definitely advantages in ranges and they're used in many other languages, but a Go design principle is to only introduce an abstraction if the benefits significantly outweigh the costs (including the cost of making the language larger). Reasonable people disagree about the costs and benefits of ranges, but this answer is my attempt to describe what I think idiomatic Go is.

答案2

得分: 62

马克·米申建议使用切片,但是没有理由使用make创建数组,并在for循环中使用返回的切片,而是可以使用通过字面值创建的数组,而且更短。

for i := range [5]int{} {
    fmt.Println(i)
}
英文:

It was suggested by Mark Mishyn to use slice but there is no reason to create array with make and use in for returned slice of it when array created via literal can be used and it's shorter

for i := range [5]int{} {
  		fmt.Println(i)
}

答案3

得分: 57

以下是对所提供代码的翻译:

这是一个比较到目前为止提出的两种方法的程序。

import (
	"fmt"

	"github.com/bradfitz/iter"
)

func p(i int) {
	fmt.Println(i)
}

func plain() {
	for i := 0; i < 10; i++ {
		p(i)
	}
}

func with_iter() {
	for i := range iter.N(10) {
		p(i)
	}
}

func main() {
	plain()
	with_iter()
}

使用以下命令编译以生成汇编代码:

go build -gcflags -S iter.go

这是 plain 函数的汇编代码(已删除非指令部分):

设置:

0035 (/home/ncw/Go/iter.go:14) MOVQ    $0,AX
0036 (/home/ncw/Go/iter.go:14) JMP     ,38

循环:

0037 (/home/ncw/Go/iter.go:14) INCQ    ,AX
0038 (/home/ncw/Go/iter.go:14) CMPQ    AX,$10
0039 (/home/ncw/Go/iter.go:14) JGE     $0,45
0040 (/home/ncw/Go/iter.go:15) MOVQ    AX,i+-8(SP)
0041 (/home/ncw/Go/iter.go:15) MOVQ    AX,(SP)
0042 (/home/ncw/Go/iter.go:15) CALL    ,p+0(SB)
0043 (/home/ncw/Go/iter.go:15) MOVQ    i+-8(SP),AX
0044 (/home/ncw/Go/iter.go:14) JMP     ,37
0045 (/home/ncw/Go/iter.go:17) RET     ,

这是 with_iter 函数的汇编代码:

设置:

0052 (/home/ncw/Go/iter.go:20) MOVQ    $10,AX
0053 (/home/ncw/Go/iter.go:20) MOVQ    $0,~r0+-24(SP)
0054 (/home/ncw/Go/iter.go:20) MOVQ    $0,~r0+-16(SP)
0055 (/home/ncw/Go/iter.go:20) MOVQ    $0,~r0+-8(SP)
0056 (/home/ncw/Go/iter.go:20) MOVQ    $type.[]struct {}+0(SB),(SP)
0057 (/home/ncw/Go/iter.go:20) MOVQ    AX,8(SP)
0058 (/home/ncw/Go/iter.go:20) MOVQ    AX,16(SP)
0059 (/home/ncw/Go/iter.go:20) PCDATA  $0,$48
0060 (/home/ncw/Go/iter.go:20) CALL    ,runtime.makeslice+0(SB)
0061 (/home/ncw/Go/iter.go:20) PCDATA  $0,$-1
0062 (/home/ncw/Go/iter.go:20) MOVQ    24(SP),DX
0063 (/home/ncw/Go/iter.go:20) MOVQ    32(SP),CX
0064 (/home/ncw/Go/iter.go:20) MOVQ    40(SP),AX
0065 (/home/ncw/Go/iter.go:20) MOVQ    DX,~r0+-24(SP)
0066 (/home/ncw/Go/iter.go:20) MOVQ    CX,~r0+-16(SP)
0067 (/home/ncw/Go/iter.go:20) MOVQ    AX,~r0+-8(SP)
0068 (/home/ncw/Go/iter.go:20) MOVQ    $0,AX
0069 (/home/ncw/Go/iter.go:20) LEAQ    ~r0+-24(SP),BX
0070 (/home/ncw/Go/iter.go:20) MOVQ    8(BX),BP
0071 (/home/ncw/Go/iter.go:20) MOVQ    BP,autotmp_0006+-32(SP)
0072 (/home/ncw/Go/iter.go:20) JMP     ,74

循环:

0073 (/home/ncw/Go/iter.go:20) INCQ    ,AX
0074 (/home/ncw/Go/iter.go:20) MOVQ    autotmp_0006+-32(SP),BP
0075 (/home/ncw/Go/iter.go:20) CMPQ    AX,BP
0076 (/home/ncw/Go/iter.go:20) JGE     $0,82
0077 (/home/ncw/Go/iter.go:20) MOVQ    AX,autotmp_0005+-40(SP)
0078 (/home/ncw/Go/iter.go:21) MOVQ    AX,(SP)
0079 (/home/ncw/Go/iter.go:21) CALL    ,p+0(SB)
0080 (/home/ncw/Go/iter.go:21) MOVQ    autotmp_0005+-40(SP),AX
0081 (/home/ncw/Go/iter.go:20) JMP     ,73
0082 (/home/ncw/Go/iter.go:23) RET     ,

因此,可以看出,即使在设置阶段完全内联化,iter 解决方案的开销要大得多。在循环阶段,循环中有一条额外的指令,但并不太糟糕。

我会使用简单的 for 循环。

英文:

Here is a program to compare the two ways suggested so far

import (
	&quot;fmt&quot;

	&quot;github.com/bradfitz/iter&quot;
)

func p(i int) {
	fmt.Println(i)
}

func plain() {
	for i := 0; i &lt; 10; i++ {
		p(i)
	}
}

func with_iter() {
	for i := range iter.N(10) {
		p(i)
	}
}

func main() {
	plain()
	with_iter()
}

Compile like this to generate disassembly

go build -gcflags -S iter.go

Here is plain (I've removed the non instructions from the listing)

setup

0035 (/home/ncw/Go/iter.go:14) MOVQ    $0,AX
0036 (/home/ncw/Go/iter.go:14) JMP     ,38

loop

0037 (/home/ncw/Go/iter.go:14) INCQ    ,AX
0038 (/home/ncw/Go/iter.go:14) CMPQ    AX,$10
0039 (/home/ncw/Go/iter.go:14) JGE     $0,45
0040 (/home/ncw/Go/iter.go:15) MOVQ    AX,i+-8(SP)
0041 (/home/ncw/Go/iter.go:15) MOVQ    AX,(SP)
0042 (/home/ncw/Go/iter.go:15) CALL    ,p+0(SB)
0043 (/home/ncw/Go/iter.go:15) MOVQ    i+-8(SP),AX
0044 (/home/ncw/Go/iter.go:14) JMP     ,37
0045 (/home/ncw/Go/iter.go:17) RET     ,

And here is with_iter

setup

0052 (/home/ncw/Go/iter.go:20) MOVQ    $10,AX
0053 (/home/ncw/Go/iter.go:20) MOVQ    $0,~r0+-24(SP)
0054 (/home/ncw/Go/iter.go:20) MOVQ    $0,~r0+-16(SP)
0055 (/home/ncw/Go/iter.go:20) MOVQ    $0,~r0+-8(SP)
0056 (/home/ncw/Go/iter.go:20) MOVQ    $type.[]struct {}+0(SB),(SP)
0057 (/home/ncw/Go/iter.go:20) MOVQ    AX,8(SP)
0058 (/home/ncw/Go/iter.go:20) MOVQ    AX,16(SP)
0059 (/home/ncw/Go/iter.go:20) PCDATA  $0,$48
0060 (/home/ncw/Go/iter.go:20) CALL    ,runtime.makeslice+0(SB)
0061 (/home/ncw/Go/iter.go:20) PCDATA  $0,$-1
0062 (/home/ncw/Go/iter.go:20) MOVQ    24(SP),DX
0063 (/home/ncw/Go/iter.go:20) MOVQ    32(SP),CX
0064 (/home/ncw/Go/iter.go:20) MOVQ    40(SP),AX
0065 (/home/ncw/Go/iter.go:20) MOVQ    DX,~r0+-24(SP)
0066 (/home/ncw/Go/iter.go:20) MOVQ    CX,~r0+-16(SP)
0067 (/home/ncw/Go/iter.go:20) MOVQ    AX,~r0+-8(SP)
0068 (/home/ncw/Go/iter.go:20) MOVQ    $0,AX
0069 (/home/ncw/Go/iter.go:20) LEAQ    ~r0+-24(SP),BX
0070 (/home/ncw/Go/iter.go:20) MOVQ    8(BX),BP
0071 (/home/ncw/Go/iter.go:20) MOVQ    BP,autotmp_0006+-32(SP)
0072 (/home/ncw/Go/iter.go:20) JMP     ,74

loop

0073 (/home/ncw/Go/iter.go:20) INCQ    ,AX
0074 (/home/ncw/Go/iter.go:20) MOVQ    autotmp_0006+-32(SP),BP
0075 (/home/ncw/Go/iter.go:20) CMPQ    AX,BP
0076 (/home/ncw/Go/iter.go:20) JGE     $0,82
0077 (/home/ncw/Go/iter.go:20) MOVQ    AX,autotmp_0005+-40(SP)
0078 (/home/ncw/Go/iter.go:21) MOVQ    AX,(SP)
0079 (/home/ncw/Go/iter.go:21) CALL    ,p+0(SB)
0080 (/home/ncw/Go/iter.go:21) MOVQ    autotmp_0005+-40(SP),AX
0081 (/home/ncw/Go/iter.go:20) JMP     ,73
0082 (/home/ncw/Go/iter.go:23) RET     ,

So you can see that the iter solution is considerably more expensive even though it is fully inlined in the setup phase. In the loop phase there is an extra instruction in the loop, but it isn't too bad.

I'd use the simple for loop.

答案4

得分: 23

iter 是一个非常小的包,它提供了一种在整数上进行迭代的语法上不同的方式。

for i := range iter.N(4) {
    fmt.Println(i)
}

Rob Pike(Go语言的作者之一)对它进行了批评

> 看起来几乎每次有人提出一种避免使用类似for循环的方式,因为它感觉太长或太麻烦,结果几乎总是比所谓更短的东西更多的按键次数。[...] 这还不包括这些“改进”带来的所有疯狂开销。

英文:

iter is a very small package that just provides a syntantically different way to iterate over integers.

for i := range iter.N(4) {
    fmt.Println(i)
}

Rob Pike (an author of Go) has criticized it:

> It seems that almost every time someone comes up with a way to avoid
doing something like a for loop the idiomatic way, because it feels
too long or cumbersome, the result is almost always more keystrokes
than the thing that is supposedly shorter. [...] That's leaving aside all the crazy overhead these "improvements" bring.

答案5

得分: 9

以下是翻译好的内容:

这是一个用于比较使用ForClause和Go range语句以及iter包的Go for语句的基准测试。

iter_test.go

package main

import (
	"testing"

	"github.com/bradfitz/iter"
)

const loops = 1e6

func BenchmarkForClause(b *testing.B) {
	b.ReportAllocs()
	j := 0
	for i := 0; i < b.N; i++ {
		for j = 0; j < loops; j++ {
			j = j
		}
	}
	_ = j
}

func BenchmarkRangeIter(b *testing.B) {
	b.ReportAllocs()
	j := 0
	for i := 0; i < b.N; i++ {
		for j = range iter.N(loops) {
			j = j
		}
	}
	_ = j
}

// It does not cause any allocations.
func N(n int) []struct{} {
	return make([]struct{}, n)
}

func BenchmarkIterAllocs(b *testing.B) {
	b.ReportAllocs()
	var n []struct{}
	for i := 0; i < b.N; i++ {
		n = iter.N(loops)
	}
	_ = n
}

输出:

$ go test -bench=. -run=.
testing: warning: no tests to run
PASS
BenchmarkForClause	    2000	   1260356 ns/op	       0 B/op	       0 allocs/op
BenchmarkRangeIter	    2000	   1257312 ns/op	       0 B/op	       0 allocs/op
BenchmarkIterAllocs	20000000	        82.2 ns/op	       0 B/op	       0 allocs/op
ok  	so/test	7.026s
$
英文:

Here's a benchmark to compare a Go for statement with a ForClause and a Go range statement using the iter package.

iter_test.go

package main

import (
	&quot;testing&quot;

	&quot;github.com/bradfitz/iter&quot;
)

const loops = 1e6

func BenchmarkForClause(b *testing.B) {
	b.ReportAllocs()
	j := 0
	for i := 0; i &lt; b.N; i++ {
		for j = 0; j &lt; loops; j++ {
			j = j
		}
	}
	_ = j
}

func BenchmarkRangeIter(b *testing.B) {
	b.ReportAllocs()
	j := 0
	for i := 0; i &lt; b.N; i++ {
		for j = range iter.N(loops) {
			j = j
		}
	}
	_ = j
}

// It does not cause any allocations.
func N(n int) []struct{} {
	return make([]struct{}, n)
}

func BenchmarkIterAllocs(b *testing.B) {
	b.ReportAllocs()
	var n []struct{}
	for i := 0; i &lt; b.N; i++ {
		n = iter.N(loops)
	}
	_ = n
}

Output:

$ go test -bench=. -run=.
testing: warning: no tests to run
PASS
BenchmarkForClause	    2000	   1260356 ns/op	       0 B/op	       0 allocs/op
BenchmarkRangeIter	    2000	   1257312 ns/op	       0 B/op	       0 allocs/op
BenchmarkIterAllocs	20000000	        82.2 ns/op	       0 B/op	       0 allocs/op
ok  	so/test	7.026s
$

答案6

得分: 8

如果你只想遍历一个范围而不使用索引或其他任何东西,这段代码对我来说完全有效。不需要额外的声明,也不需要_。尽管我没有检查性能。

for range [N]int{} {
    // Body...
}

附注:我刚开始学习Go语言的第一天。如果这种方法是错误的,请指正。

英文:

If you want to just iterate over a range w/o using and indices or anything else, this code sample worked just fine for me. No extra declaration needed, no _. Haven't checked the performance, though.

for range [N]int{} {
	// Body...
}

P.S. The very first day in GoLang. Please, do critique if it's a wrong approach.

答案7

得分: 6

虽然我理解你对缺少这种语言特性的担忧,但你可能只需要使用普通的for循环。随着你编写更多的Go代码,你可能会发现自己对此更加满意。

我编写了这个iter包,它使用一个简单、惯用的for循环通过chan int返回值,旨在改进https://github.com/bradfitz/iter中的设计。后者被指出存在缓存和性能问题,以及一个巧妙但奇怪和不直观的实现。我的版本与之相同:

package main

import (
	"fmt"
	"github.com/drgrib/iter"
)

func main() {
	for i := range iter.N(10) {
		fmt.Println(i)
	}
}

然而,基准测试表明使用通道是一个非常昂贵的选项。可以通过在我的包中的iter_test.go中运行以下命令来比较这3种方法的性能:

go test -bench=. -run=.

以下是性能表现的具体数据:

BenchmarkForMany-4            	     5000	    329956 ns/op	       0 B/op	       0 allocs/op
BenchmarkDrgribIterMany-4     	        5	 229904527 ns/op	     195 B/op	       1 allocs/op
BenchmarkBradfitzIterMany-4   	     5000	    337952 ns/op	       0 B/op	       0 allocs/op

BenchmarkFor10-4              	500000000	      3.27 ns/op	       0 B/op	       0 allocs/op
BenchmarkDrgribIter10-4       	   500000	   2907 ns/op	 	      96 B/op	       1 allocs/op
BenchmarkBradfitzIter10-4     	100000000	     12.1 ns/op	  	       0 B/op	       0 allocs/op

这个基准测试还显示了对于循环大小为10bradfitz的解决方案在性能上表现不如内置的for循环。

简而言之,迄今为止还没有发现一种方法可以在提供类似Python和Ruby中的[0,n)的简单语法的同时,复制内置的for循环的性能。

这真是遗憾,因为Go团队可能很容易通过向编译器添加一个简单的规则来将类似下面的代码:

for i := range 10 {
	fmt.Println(i)
}

转换为与for i := 0; i < 10; i++相同的机器码。

然而,公平地说,在编写了自己的iter.N之后(但在对其进行基准测试之前),我回顾了最近编写的程序,看看哪些地方可以使用它。实际上并没有太多的地方可以使用它。只有一个地方,在我的代码中的一个非关键部分,我可以不使用更完整、默认的for循环。

因此,虽然从原则上看,这可能看起来是对语言的巨大失望,但你可能会发现,就像我一样,实际上你并不真正需要它。就像Rob Pike在泛型中所说的那样,你可能并不会像你想象的那样非常需要这个特性。

英文:

While I commiserate with your concern about lacking this language feature, you're probably just going to want to use a normal for loop. And you'll probably be more okay with that than you think as you write more Go code.

I wrote this iter package — which is backed by a simple, idiomatic for loop that returns values over a chan int — in an attempt to improve on the design found in https://github.com/bradfitz/iter, which has been pointed out to have caching and performance issues, as well as a clever, but strange and unintuitive implementation. My own version operates the same way:

package main

import (
	&quot;fmt&quot;
	&quot;github.com/drgrib/iter&quot;
)

func main() {
	for i := range iter.N(10) {
		fmt.Println(i)
	}
}

However, benchmarking revealed that the use of a channel was a very expensive option. The comparison of the 3 methods, which can be run from iter_test.go in my package using

go test -bench=. -run=.

quantifies just how poor its performance is

BenchmarkForMany-4            	     5000	    329956 ns/op	       0 B/op	       0 allocs/op
BenchmarkDrgribIterMany-4     	        5	 229904527 ns/op	     195 B/op	       1 allocs/op
BenchmarkBradfitzIterMany-4   	     5000	    337952 ns/op	       0 B/op	       0 allocs/op

BenchmarkFor10-4              	500000000	      3.27 ns/op	       0 B/op	       0 allocs/op
BenchmarkDrgribIter10-4       	   500000	   2907 ns/op	 	      96 B/op	       1 allocs/op
BenchmarkBradfitzIter10-4     	100000000	     12.1 ns/op	  	       0 B/op	       0 allocs/op

In the process, this benchmark also shows how the bradfitz solution underperforms in comparison to the built-in for clause for a loop size of 10.

In short, there appears to be no way discovered so far to duplicate the performance of the built-in for clause while providing a simple syntax for [0,n) like the one found in Python and Ruby.

Which is a shame because it would probably be easy for the Go team to add a simple rule to the compiler to change a line like

for i := range 10 {
	fmt.Println(i)
}

to the same machine code as for i := 0; i &lt; 10; i++.

However, to be fair, after writing my own iter.N (but before benchmarking it), I went back through a recently written program to see all the places I could use it. There actually weren't many. There was only one spot, in a non-vital section of my code, where I could get by without the more complete, default for clause.

So while it may look like this is a huge disappointment for the language in principle, you may find — like I did — that you actually don't really need it in practice. Like Rob Pike is known to say for generics, you might not actually miss this feature as much as you think you will.

答案8

得分: 1

你也可以查看github.com/wushilin/stream。

它是一个类似于java.util.stream的惰性流概念。

// 它实际上并不分配这10个元素。
stream1 := stream.Range(0, 10)

// 打印每个元素。
stream1.Each(print)

// 对每个元素加3,但这是一个惰性操作。
// 只有在消费流时才会进行加法操作。
stream2 := stream1.Map(func(i int) int {
return i + 3
})

// 好吧,这里消费了流 => 返回stream2的总和。
stream2.Reduce(func(i, j int) int {
return i + j
})

// 创建包含5个元素的流
stream3 := stream.Of(1, 2, 3, 4, 5)

// 从数组创建流
stream4 := stream.FromArray(arrayInput)

// 过滤stream3,只保留大于2的元素,
// 并返回总和,即12
stream3.Filter(func(i int) bool {
return i > 2
}).Sum()

希望对你有所帮助。

英文:

You can also check out
github.com/wushilin/stream

It is a lazy stream like concept of java.util.stream.

// It doesn&#39;t really allocate the 10 elements.
stream1 := stream.Range(0, 10)

// Print each element.
stream1.Each(print)

// Add 3 to each element, but it is a lazy add.
// You only add when consume the stream
stream2 := stream1.Map(func(i int) int {
	return i + 3
})

// Well, this consumes the stream =&gt; return sum of stream2.
stream2.Reduce(func(i, j int) int {
	return i + j
})

// Create stream with 5 elements
stream3 := stream.Of(1, 2, 3, 4, 5)

// Create stream from array
stream4 := stream.FromArray(arrayInput)

// Filter stream3, keep only elements that is bigger than 2,
// and return the Sum, which is 12
stream3.Filter(func(i int) bool {
	return i &gt; 2
}).Sum()

Hope this helps

答案9

得分: 1

我用Golang编写了一个模仿Python的range函数的包:

包地址:https://github.com/thedevsaddam/iter

package main

import (
	"fmt"

	"github.com/thedevsaddam/iter"
)

func main() {
	// 序列:0-9
	for v := range iter.N(10) {
		fmt.Printf("%d ", v)
	}
	fmt.Println()
	// 输出:0 1 2 3 4 5 6 7 8 9

	// 序列:5-9
	for v := range iter.N(5, 10) {
		fmt.Printf("%d ", v)
	}
	fmt.Println()
	// 输出:5 6 7 8 9

	// 序列:1-9,增量为2
	for v := range iter.N(5, 10, 2) {
		fmt.Printf("%d ", v)
	}
	fmt.Println()
	// 输出:5 7 9

	// 序列:a-e
	for v := range iter.L('a', 'e') {
		fmt.Printf("%s ", string(v))
	}
	fmt.Println()
	// 输出:a b c d e
}

注意:这只是我为了好玩而写的!顺便说一句,有时候可能会有帮助。

英文:

I have written a package in Golang which mimic the Python's range function:

Package https://github.com/thedevsaddam/iter

package main

import (
	&quot;fmt&quot;

	&quot;github.com/thedevsaddam/iter&quot;
)

func main() {
	// sequence: 0-9
	for v := range iter.N(10) {
		fmt.Printf(&quot;%d &quot;, v)
	}
	fmt.Println()
	// output: 0 1 2 3 4 5 6 7 8 9

	// sequence: 5-9
	for v := range iter.N(5, 10) {
		fmt.Printf(&quot;%d &quot;, v)
	}
	fmt.Println()
	// output: 5 6 7 8 9

	// sequence: 1-9, increment by 2
	for v := range iter.N(5, 10, 2) {
		fmt.Printf(&quot;%d &quot;, v)
	}
	fmt.Println()
	// output: 5 7 9

	// sequence: a-e
	for v := range iter.L(&#39;a&#39;, &#39;e&#39;) {
		fmt.Printf(&quot;%s &quot;, string(v))
	}
	fmt.Println()
	// output: a b c d e
}

> Note: I have written for fun! Btw, sometimes it may be helpful

答案10

得分: 1

这是一个紧凑、动态的版本,不依赖于iter(但工作方式类似):

package main

import (
	"fmt"
)

// N 是一个未分配结构体的别名
func N(size int) []struct{} {
	return make([]struct{}, size)
}

func main() {
	size := 1000
	for i := range N(size) {
		fmt.Println(i)
	}
}

如果需要的话,可以对size进行一些调整,使其成为uint64类型,但这就是要点。

英文:

Here is a compact, dynamic version that doesn't depend on iter (but works similarly):

package main

import (
	&quot;fmt&quot;
)

// N is an alias for an unallocated struct
func N(size int) []struct{} {
	return make([]struct{}, size)
}

func main() {
	size := 1000
	for i := range N(size) {
		fmt.Println(i)
	}
}

With some tweaks size could be of type uint64 (if needed) but that's the gist.

答案11

得分: 0

问题不在于范围,问题在于如何计算切片的末尾
使用固定数字10,简单的for循环是可以的,但是使用计算得到的size(例如bfl.Size())会在每次迭代中进行函数调用。使用int32的简单range可以帮助解决这个问题,因为它只会对bfl.Size()进行一次求值。

type BFLT PerfServer   
  func (this *BFLT) Call() {
    bfl := MqBufferLCreateTLS(0)                                                                                   
    
    for this.ReadItemExists() {                                                                                    
      bfl.AppendU(this.ReadU())                                                                                    
    }
    
    this.SendSTART()
    
    // size := bfl.Size() 
    for i := int32(0); i < bfl.Size() /* size */; i++ {                                                                             
      this.SendU(bfl.IndexGet(i))                                                                                  
    }
    
    this.SendRETURN()
  }
英文:

The problem is not the range, the problem is how the end of slice is calculated.
with a fixed number 10 the simple for loop is ok but with a calculated size like bfl.Size() you get a function-call on every iteration. A simple range over int32 would help because this evaluate the bfl.Size() only once.

type BFLT PerfServer   
  func (this *BFLT) Call() {
    bfl := MqBufferLCreateTLS(0)                                                                                   
    for this.ReadItemExists() {                                                                                    
      bfl.AppendU(this.ReadU())                                                                                    
    }
    this.SendSTART()
    // size := bfl.Size() 
    for i := int32(0); i &lt; bfl.Size() /* size */; i++ {                                                                             
      this.SendU(bfl.IndexGet(i))                                                                                  
    }
    this.SendRETURN()
  }

答案12

得分: -1

package main

import "fmt"

func main() {

    nums := []int{2, 3, 4}
    for _, num := range nums {
        fmt.Println(num, sum)
    }
}
package main

import "fmt"

func main() {

    nums := []int{2, 3, 4}
    for _, num := range nums {
        fmt.Println(num, sum)
    }
}
package main

import "fmt"

func main() {

    nums := []int{2, 3, 4}
    for _, num := range nums {
        fmt.Println(num, sum)
    }
}
英文:
package main

import &quot;fmt&quot;

func main() {

    nums := []int{2, 3, 4}
    for _, num := range nums {
       fmt.Println(num, sum)	
    }
}

huangapple
  • 本文由 发表于 2014年2月22日 13:39:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/21950244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定