关于 Golang Go语言中 range 的使用
关于 Golang Go语言中 range 的使用
func main() {
var a []int
a = append(a, 1, 2)
for _, _ = range a {
a = append(a, 1)
}
fmt.Println(a)
}
这个时候 range 不会无限循环,说明 range 在循环之前就创建了 a 的副本,a 的改动不会影响 range 的执行。(这一段持不肯定态度)
然后
func main() {
var a []int
a = append(a, 1, 2, 3, 4, 5, 4, 6, 6)
for i, t := range a {
if t == 4 }
a = append(a[:i], a[i+1:]...)
}
}
fmt.Println(a)
}
如果 range 提前保存了 a 的副本,a 中含有两个 4,第一次可以正确删除 4,第二次删除 4 的时候 i 的值应该为 a 的副本中的下标,应该会删除错误的数字,但事实是 go 正确的删除了两个 4
有没有人给小弟解个惑,纠结半天了
更多关于关于 Golang Go语言中 range 的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我们遇到什么困难,都不要怕,微笑着面对它,消除恐惧的最好办法就是面对恐惧,加油,奥利给!
你少了一句“坚持,才是胜利”
我记得 go range 的 value 是值引用,那 key 是不是也是这样
猜测:range 不是创建的副本,而是获取了长度
你这里的正确只是碰巧正确而已,你可以把 a = append(a, 1, 2, 3, 4, 5, 4, 6, 6) 改成 a = append(a, 1, 2, 3, 4, 4, 4, 6, 6) 试试。
而且根据 https://golang.org/ref/spec#For_statements 里的 “For statements with range clause” 的第一种情况的说明,range 并不会索引到数组或者切片,而是索引到数组或切片的元素。
而不会无线循环的原因来源于这一句:“The range expression x is evaluated once before beginning the loop, with one exception: if at most one iteration variable is present and len(x) is constant, the range expression is not evaluated.”
那对于这种需求有什么优雅的解决方法没,现在能想到的只有自己写个 index 方法或者单独起个数组记录需要删除的元素
#7 你这是 filter 的需求,可以参考这个 https://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating,其实就是用切片而不是用数组,由于切片是共享同一个 “backing array”,所以不会有额外的消耗。
slice 其实就是一个 struct,range 语句会复制这个 struct,而不是存放元素的 array,所以修改 slice 只是修改另一个 struct,对 range 所用的 struct 没有影响。
但是两个 struct 可能用到同一个 array,也可能用不同的 array,因为 append 可能扩容
删除 slice 里的特定元素有好几种方法,具体看: https://github.com/golang/go/wiki/SliceTricks
在 Go 语言中,range
关键字是一种强大且灵活的工具,用于遍历数组、切片、映射(map)、字符串和通道(channel)。下面是对 range
在不同情况下的基本用法说明:
-
数组和切片:
nums := []int{1, 2, 3} for index, value := range nums { fmt.Println(index, value) }
这里,
index
是元素的索引,value
是对应的元素值。你也可以只获取索引或值,例如for index := range nums
或for value := range nums
。 -
映射(map):
myMap := map[string]int{"a": 1, "b": 2} for key, value := range myMap { fmt.Println(key, value) }
在映射中,
key
是键,value
是对应的值。 -
字符串:
str := "hello" for index, runeValue := range str { fmt.Println(index, runeValue) }
对于字符串,
index
是字节索引,runeValue
是对应的 Unicode 码点(rune)。 -
通道(channel):
ch := make(chan int, 3) ch <- 1 ch <- 2 close(ch) for value := range ch { fmt.Println(value) }
在通道中,
range
会一直读取直到通道被关闭。
range
使得遍历这些数据结构变得简单且直观,是 Go 语言中不可或缺的一部分。