golang关于for循环的用法

yanglikai · · 1172 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

for...range支持迭代 数组、切片、字符串、map、只读channel或可读可写channel;

for...range迭代类型不同返回值不同,数组、切片、字符串返回下标和值,map返回键和值,channel返回值;

1、for与for range在遍历字符串时的差别

package main

import "fmt"

func main() {
	str := "abcd中国人"
	n := len(str)
	for i := 0; i < n; i++ {
		fmt.Printf("%c", str[i]) //abcd笃志弘毅
	}
	fmt.Println()
	for i, v := range str {
		fmt.Printf("str[%d]=%c", i, v)
		//str[0]=astr[1]=bstr[2]=cstr[3]=dstr[4]=中str[7]=国str[10]=人
	}
}

for遍历字符串时是按字节(byte)进行遍历,超出一个字节的编码字符会出现乱码;

for...range遍历字符串时是按字符(rune)进行遍历;

2、for...range遍历切片或数组

2.1 迭代切片时相当于遍历切片副本,原始切片的append或再切片不影响整个迭代

package main

import "fmt"

func main() {
	slice := []int{1, 2, 3, 4, 5, 6}
	for i, v := range slice {
		//迭代切片相当于temp:=slice[:],遍历temp切片
		//slice的append或再切片slice[1:2]不影响整个迭代
		slice = append(slice, 0)
		slice = slice[0:len(slice)]
		fmt.Printf("slice[%d]=%d ", i, v)
		//slice[0]=1 slice[1]=2 slice[2]=3 slice[3]=4 slice[4]=5 slice[5]=6
	}
	fmt.Println("\n", slice) // [1 2 3 4 5 6 0 0 0 0 0 0]
}

2.2 值类型的迭代修改不影响原始数据,指针类型的迭代修改会影响原始数据

package main

import "fmt"

func main() {
	//切片
	slice := []int{1, 2, 3, 4, 5, 6}
	for _, v := range slice {
		v += v
	}
	fmt.Println(slice) //[1 2 3 4 5 6]
	//map
	m := map[int]*int{}
	m[1] = new(int)
	m[2] = new(int)
	*m[1] = 1
	*m[2] = 2
	fmt.Println(*m[1], *m[2]) //1 2
	for _, v := range m {
		*v++
	}
	fmt.Println(*m[1], *m[2]) //2 3
}

3、for...range遍历map

3.1 访问是随机的,遍历结果可能不一样

package main

import "fmt"

func main() {
	m := map[int]int{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
	for k, v := range m {
		fmt.Printf("%v %v,", k, v) //2 2,3 3,4 4,0 0,1 1,
	}
}

3.2 可以正常进行删除操作,因为迭代使用的是拷贝

package main

import "fmt"

func main() {
	m := map[int]*int{}
	m[1] = new(int)
	m[2] = new(int)
	*m[1] = 1
	*m[2] = 2
	fmt.Println(*m[1], *m[2]) //1 2
	for k, v := range m {
		delete(m, k)
		*v++
		fmt.Printf("%v ", *v) //2 3
	}
	fmt.Println(m) //map[]
}

3.3 可以正常进行添加操作,由于map底层是哈希表,哈希表的元素不具备顺序性,所以新添加的元素不一定会出现在后续的迭代中

package main

import "fmt"

func main() {
	m := map[int]string{1: "一", 2: "二"}
	for k, v := range m {
		m[k+2] = "测试"
		fmt.Println(k, v); //遍历结束后这行代码可能只输出了2行结果,也可能输出N(N>2)行结果
	}
	fmt.Println(m); //结果不定,可能是map[1:一 2:二 3:测试 4:测试 5:测试 6:测试]
}

转载来源:https://www.cnblogs.com/dzhy/p/10977779.html


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1172 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传