Go语言范围Range的具体使用
Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。
// 格式如下 // 代码中的key和value是可以省略的 for key, value := range oldMap { newMap[key] = value }
// 如果只想读取key,格式如下 for key := range oldMap // 或者 for key, _ := range oldMap
// 如果只想读取value,格式如下 for _, value := range oldMap
// 遍历简单的数组,2**%d的结果为索引对应的次方数 package main import "fmt" var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} func main() { /* 2**0 = 1 2**1 = 2 2**2 = 4 2**3 = 8 2**4 = 16 2**5 = 32 2**6 = 64 2**7 = 128 */ for i, v := range pow { fmt.Printf("2**%d = %d\n", i, v) } }
# 程序输出
2**0 = 1
2**1 = 2
2**2 = 4
2**3 = 8
2**4 = 16
2**5 = 32
2**6 = 64
2**7 = 128
// for循环的range格式可以省略key和value package main import "fmt" func main() { map1 := make(map[int]float32) map1[1] = 1.0 map1[2] = 2.0 map1[3] = 3.0 map1[4] = 4.0 /* key is: 1 - value is: 1.000000 key is: 2 - value is: 2.000000 key is: 3 - value is: 3.000000 key is: 4 - value is: 4.000000 */ // 读取 key 和 value for key, value := range map1 { fmt.Printf("key is: %d - value is: %f\n", key, value) } /* key is: 1 key is: 2 key is: 3 key is: 4 */ // 读取 key for key := range map1 { fmt.Printf("key is: %d\n", key) } /* value is: 1.000000 value is: 2.000000 value is: 3.000000 value is: 4.000000 */ // 读取 value for _, value := range map1 { fmt.Printf("value is: %f\n", value) } }
// range遍历其他数据结构 package main import "fmt" func main() { //这是我们使用 range 去求一个 slice 的和。使用数组跟这个很类似 nums := []int{2, 3, 4} sum := 0 for _, num := range nums { sum += num } // sum: 9 fmt.Println("sum:", sum) //在数组上使用 range 将传入索引和值两个变量。上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。 for i, num := range nums { if num == 3 { // index: 1 fmt.Println("index:", i) } } //range 也可以用在 map 的键值对上。 kvs := map[string]string{"a": "apple", "b": "banana"} /* a -> apple b -> banana */ for k, v := range kvs { fmt.Printf("%s -> %s\n", k, v) } /* 0 103 1 111 */ //range也可以用来枚举 Unicode 字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。 for i, c := range "go" { fmt.Println(i, c) } }
// Range 简单循环 package main import "fmt" func main() { nums := []int{1, 2, 3, 4} length := 0 for range nums { length++ } // 4 fmt.Println(length) }
// 通过 range 获取参数列表 package main import ( "fmt" "os" ) func main() { // 1 fmt.Println(len(os.Args)) for _, arg := range os.Args { // C:\Users\zhangshixing\AppData\Local\Temp\___go_build_hello_go.exe fmt.Println(arg) } }
// Go 中的中文采用UTF-8编码,因此逐个遍历字符时必须采用for-each形式 package main import "fmt" func main() { // str: hello // 0x68 h, 0x65 e, 0x6c l, 0x6c l, 0x6f o, // 0x68, 0x65, 0x6c, 0x6c, 0x6f, printStr("hello") fmt.Println() fmt.Println() // str: 中国人 // 0x4e2d 中, 0x56fd 国, 0x4eba 人, // 0xe4, 0xb8, 0xad, 0xe5, 0x9b, 0xbd, 0xe4, 0xba, 0xba, printStr("中国人") } func printStr(s string) { fmt.Println("str: " + s) for _, v := range s { fmt.Printf("0x%x %c, ", v, v) } fmt.Println() for i := 0; i < len(s); i++ { fmt.Printf("0x%x, ", s[i]) } }
涉及指针时需要注意,v 是个单独的地址:
package main import "fmt" func main() { nums := [3]int{5, 6, 7} /* 源值地址: 0xc00000c108 value的地址: 0xc000016098 源值地址: 0xc00000c110 value的地址: 0xc000016098 源值地址: 0xc00000c118 value的地址: 0xc000016098 */ for k, v := range nums { fmt.Println("源值地址:", &nums[k], " \t value的地址:", &v) } }
range复用临时变量:
package main import "sync" func main() { wg := sync.WaitGroup{} si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for i := range si { wg.Add(1) go func() { print(i) wg.Done() }() } wg.Wait() }
# 程序输出
9999999999
导致这样结果的原因是:
(1)、for range 下的迭代变量i的值是共用的。
(2)、main函数所在的 goroutine 和后续启动的 goroutines 存在竞争关系。
package main import "sync" func main() { wg := sync.WaitGroup{} si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for i := range si { wg.Add(1) // 这里有一个实参到形参的值拷贝 go func(a int) { print(a) wg.Done() }(i) } wg.Wait() }
# 程序输出
9865207314
到此这篇关于Go语言范围Range的具体使用的文章就介绍到这了,更多相关Go语言范围Range内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Golang程序中使用Prometheus的client_golang库
这篇文章主要介绍了Golang程序中使用Prometheus的client_golang库,Prometheus 是一个开源的监控和警报工具包,用于收集和处理应用程序和系统的指标数据。Prometheus 提供了多种客户端库,可以轻松地集成到各种编程语言中2023-04-04Go语言之io.ReadAtLeast函数的基本使用和原理解析
io.ReadAtLeast函数是Go语言标准库提供的一个工具函数,能够从数据源读取至少指定数量的字节数据到缓冲区中,这篇文章主要介绍了io.ReadAtLeast函数的相关知识,需要的朋友可以参考下2023-07-07
最新评论