for 和 for range有什么区别?

已邀请:

root666 - 90后

赞同来自: dncmn 想github登录

主要是使用场景不同

for可以

  1. 遍历arrayslice
  2. 遍历key为整型递增的map
  3. 遍历string

for range可以完成所有for可以做的事情,却能做到for不能做的,包括

  1. 遍历keystring类型的map并同时获取keyvalue
  2. 遍历channel

请参考 文档,欢迎补充修正。

jinheking

赞同来自:

for 就类似于C里面的for

for  i := 0; i < 10; i++ {
        //看这个是不是很像C语言了?
}

for range 类似于foreach

//重磅推荐下面的写法,相当于很多语言里面的foreach
//for range 结构
sunnyMap := map[string]int{"Mon": 0, "Tue": 1, "Wed": 2, "Thu": 3, "Fri": 4, "Sat": 5, "Sun": 6}

for key, value := range sunnyMap {
    fmt.Printf("%d->%s\r\n", key, value)
}

simple - 既要有梦想,又要有实力

赞同来自:

for就是一个普通的循环语义,和其他语言相差无几,只是把其他语言的while, do while的语义也糅合到了for语义中。
for range更像是为了数据容器(如array, slice, map...)而生的遍历容器元素的方式(迭代器模式),只是Go语言现在还没有像C++等语言那样把for range的语义对外开放,无法让我们在实现一个数据容器(如linkedlist, queue...)之后, 再实现一些"规定"的方法(为了适配for range语义)就可以使用for range遍历我们自己数据容器元素(这样可以让我们不管在遍历原生数据容器,还是自定义数据容器都可以统一使用for range,风格统一)。因此当前如果我们自己实现一些数据容器(如sync.Map),如果用普通的for循环无法遍历其元素,就必须自己实现一些显式的遍历方法,如sync.Map的Range方法。

winnie

赞同来自:

range是拷贝地址的, 操作大数据的时候很消耗内存. 是不是操作大数据的时候用for, 数据量小的时候用range?

ioco - 游戏服务器开发

赞同来自:

两个其实一样,range的实现还是for,额外声明了两个变量,性能差不多。range有一些特殊的用法,如:range chan

viewer

赞同来自:

range是拷贝地址的?

qiyin

赞同来自:

推荐看 《golang for语句完全指南》

一下引用其中的一段介绍:

for语句的内部实现-array golang的for语句,对于不同的格式会被编译器编译成不同的形式,如果要弄明白需要看 golang的编译器和相关数据结构的源码, 数据结构源码还好,但是编译器是用C++写的,本人C++是个弱鸡,这里只讲array内部实现。

// The loop we generate:
//   len_temp := len(range)
//   range_temp := range
//   for index_temp = 0; index_temp < len_temp; index_temp++ {
//           value_temp = range_temp[index_temp]
//           index = index_temp
//           value = value_temp
//           original body
//   }

// 例如代码:  
array := [2]int{1,2}
for k,v := range array {
    f(k,v)
}

// 会被编译成:  
len_temp := len(array)
range_temp := array
for index_temp = 0; index_temp < len_temp; index_temp++ {
    value_temp = range_temp[index_temp]
    k = index_temp
    v = value_temp
    f(k,v)
}

所以像遍历一个数组,最后生成的代码很像C语言中的遍历,而且有两个临时变量index_temp,value_temp, 在整个遍历中一直复用这两个变量。所以会导致开头问题2的问题(详细解答会在后边)。

要回复问题请先登录注册