Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 有没有一种方法可以迭代一系列整数?_Loops_Go_Integer_Range - Fatal编程技术网

Loops 有没有一种方法可以迭代一系列整数?

Loops 有没有一种方法可以迭代一系列整数?,loops,go,integer,range,Loops,Go,Integer,Range,Go的范围可以迭代地图和切片,但我想知道是否有一种方法可以迭代一系列数字,比如: for i := range [1..10] { fmt.Println(i) } 或者有并没有一种方法可以像Ruby一样在Go中表示整数的范围?是一个非常小的包,它只是提供了一种语法上不同的方法来迭代整数 for i := range iter.N(4) { fmt.Println(i) } 罗布·派克(Go的作者): 似乎几乎每次有人想办法避免 以惯用的方式做类似于for循环的事情,因为它感

Go的范围可以迭代地图和切片,但我想知道是否有一种方法可以迭代一系列数字,比如:

for i := range [1..10] {
    fmt.Println(i)
}
或者有并没有一种方法可以像Ruby一样在Go中表示整数的范围?

是一个非常小的包,它只是提供了一种语法上不同的方法来迭代整数

for i := range iter.N(4) {
    fmt.Println(i)
}
罗布·派克(Go的作者):

似乎几乎每次有人想办法避免 以惯用的方式做类似于for循环的事情,因为它感觉 太长或太麻烦,结果几乎总是更多的击键 而不是应该更短的东西。[…]这就撇开了这些“改进”带来的所有疯狂开销


您可以而且应该只编写for循环。简单、明显的代码就是最好的选择

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

i:=1的
;我这里有一个程序来比较迄今为止提出的两种方法

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()
}
这里是简单的(我已经从清单中删除了非指令)

设置

环路

这是国际热核实验堆

设置

环路

所以你可以看到,国际热核实验堆的解决方案是相当昂贵的,即使它是完全内联在安装阶段。在循环阶段,循环中有一条额外的指令,但这并不太糟糕


我会使用简单的for循环。

这里有一个基准来比较Go
for
语句和for子句,以及使用
iter
包的Go
range
语句

iter\u测试开始

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
}
你也可以退房 github.com/wushilin/stream

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

// It doesn'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 => 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 > 2
}).Sum()

希望这能有所帮助虽然我很同情您对缺少此语言功能的担忧,但您可能只想使用正常的
for
循环。当您编写更多的Go代码时,您可能会比您想象的更能接受这一点

我编写了一个简单、惯用的
for
循环,该循环返回的值超过
chan int
,试图改进中的设计,该设计被指出存在缓存和性能问题,以及一个聪明但奇怪且不直观的实现。我自己的版本的操作方式相同:

package main

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

func main() {
    for i := range iter.N(10) {
        fmt.Println(i)
    }
}
然而,基准测试显示,使用渠道是一种非常昂贵的选择。这三种方法的比较,可以从我的包中的
iter_test.go
运行,使用

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
在此过程中,该基准还显示了
bradfitz
解决方案在循环大小为
10
的情况下,与内置的
for
子句相比,其表现如何

简言之,到目前为止,似乎还没有办法复制内置的
for
子句的性能,同时为
[0,n)
提供简单的语法,就像Python和Ruby中的语法一样

这是一个遗憾,因为Go团队可能很容易向编译器添加一个简单的规则来更改这样的行

for i := range 10 {
    fmt.Println(i)
}
与i:=0;i<10;i++
相同的机器代码

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


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

马克·米什恩建议使用slice,但在实践中,你可以使用它当通过文字创建的数组可以使用且更短时,e没有理由创建带有
make
的数组,并在
中使用
for
返回的片段

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

如果您只想使用and索引或其他任何东西在一个范围内进行迭代,那么这个代码示例对我来说效果很好。不需要额外的声明,也不需要
\uu
。不过,我还没有检查性能

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

请注意,在GoLang的第一天。如果这是一个错误的方法,请进行批评。

我在GoLang中编写了一个模拟Python范围函数的包:

包装

主程序包
进口(
“fmt”
“github.com/thedevsaddam/iter”
)
func main(){
//顺序:0-9
对于v:=范围iter.N(10){
格式打印F(“%d”,v)
}
fmt.Println()
//输出:01 2 3 4 5 6 7 8 9
//顺序:5-9
对于v:=范围iter.N(5,10){
格式打印F(“%d”,v)
}
fmt.Println()
//产出:56789
//顺序:1-9,增加2
对于v:=范围iter.N(5,10,2){
格式打印F(“%d”,v)
}
fmt.Println()
//产出:579
//顺序:a-e
对于v:=范围iter.L('a','e'){
fmt.Printf(“%s”,字符串(v))
}
fmt.Println()
//输出:a b c d e
}
注意:我写这篇文章是为了好玩!顺便说一句,有时候可能会有帮助


这是一个紧凑、动态的版本,它不依赖于iter(国际热核聚变实验堆)(但工作原理类似):

通过一些调整,
size
可以是
uint64
(如果需要)类型,但这是要点。

问题不在于范围,而在于如何计算片尾。 对于固定的
10
for
循环,简单的
for
是可以的,但是对于像
bfl.size()
这样经过计算的
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()
  }
类型BFLT PerfServer
func(此*BFLT)调用(){
bfl:=MqBufferLCreateTLS(0)
对于此。ReadItemExists(){
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
for i := range 10 {
    fmt.Println(i)
}
for i := range [5]int{} {
        fmt.Println(i)
}
package main

import "fmt"

func main() {

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

import (
    "fmt"
)

// 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)
    }
}

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()
  }