Go 知识for-range

Go 知识for-range

  • 1. for-range 的用法
    • 1.1 数组
    • 1.2 切片
    • 1.3 字符串
    • 1.4 map
    • 1.5 chan
  • 2. 原理
    • 2.1 数组
    • 2.2 切片
    • 2.3 字符串
    • 2.4 map
    • 2.5 chan
  • 3. 总结

https://a18792721831.github.io/

1. for-range 的用法

for-range 表达式用于遍历集合元素,比传统的for更加简单直观。
for-range 的表达式一般格式:

    for index, value := range data {//....}

for-range 一般可以返回两个值,对于不同类型的data有不同的返回值。
对于数组,返回下标和值。
对于切片,返回下标和值。
对于string,返回下标和值。
对于map,返回key和value。
对于chan,返回值,只会返回一个元素。

1.1 数组

	arr := [5]int{1, 2, 3, 4, 5}for i := range arr {fmt.Println(arr[i])}fmt.Println()for i, v := range arr {fmt.Printf("i=%d,v=%d\n", i, v)}

在这里插入图片描述

1.2 切片

	arr := []int{1, 2, 3, 4, 5}for i := range arr {fmt.Println(arr[i])}fmt.Println()arr = append(arr, 6, 7, 8, 9)for i, v := range arr {fmt.Printf("i=%d,v=%d\n", i, v)}

在这里插入图片描述

1.3 字符串

	str := "hello world"for i := range str {fmt.Println(str[i])}fmt.Println()for i, v := range str {fmt.Printf("i=%d,v=%c\n", i, v)}

在这里插入图片描述

需要注意的是,对于中英文,因为编码的方式不同,每个字符的占用空间不同,就会出现下标不连续的问题。

	str := "你好,世界"for i := range str {fmt.Println(str[i])}fmt.Println()for i, v := range str {fmt.Printf("i=%d,v=%c\n", i, v)}

在这里插入图片描述

1.4 map

	str := map[string]int{"one":   1,"two":   2,"three": 3,"four":  4,"five":  5,}for i := range str {fmt.Println(str[i])}fmt.Println()for k, v := range str {fmt.Printf("i=%s,v=%d\n", k, v)}

在这里插入图片描述

1.5 chan

	ch := make(chan string, 10)ch <- "h"ch <- "e"ch <- "l"ch <- "l"ch <- "o"for i := range ch {fmt.Println(i)}//fmt.Println()//for k, v := range ch {//	fmt.Printf("i=%s,v=%d\n", k, v)//}

在这里插入图片描述

因为chan里面没有数据了,所以就阻塞了,并不会自动结束哦。
当你视图用两个变量接收返回值的时候,就会编译失败
在这里插入图片描述

2. 原理

for-range是在编译的时候,转换为传统的for语句。
需要注意,下面都是伪代码,使用常见的语法规则进行描述。

因为在for-range中使用了 := 短定义并赋值的方式,所以使用for-range的时候,第二个值会进行变量拷贝,对于大数据的for-range,可能会导致性能变差。

2.1 数组

    len_temp := len(arr)data := arrfor index_temp = 0; index_temp < len_temp; index_temp++ {value_temp = data[index_temp]index = index_tempvalue = value_temp// 执行 for-range 里面的代码// .....}

需要注意的一个,在数组中,len和cap是两个值,如果len=5,cap=10,在遍历过程中,对于第6个元素进行赋值,那么是无法遍历到的。因为在遍历开始的时候,就已经使用len获取到了遍历范围了。

2.2 切片

    len_temp := len(sli)data := slifor index_temp = 0; index_temp < len_temp; index_temp++ {value_temp = data[index_temp]index = index_tempvalue = value_temp// 执行 for-range 里面的代码// .....}

切片与数组基本上相同。

2.3 字符串

    len_temp := len(str)var next_index_temp intfor index_temp = 0; index_temp < len_temp; index_temp = nex_index_temp {value_temp = rune(str[index_temp])if value_temp < utf8.RuneSize {next_index_temp = index_temp + 1} else {value_temp, next_index_temp = decoderune(str, index_temp)}index = index_tempvalue = value_temp// 执行 for-range 里面的代码// .....}

因为不同的字符集,占用的长度不同,所以这里会对是否是utf8字符集字符进行判断,并进行不同的处理。
比如:
在这里插入图片描述

2.4 map

    var temp *mapinit_map(type, data, &temp)for ; temp != nil; temp = iter_next() {index_temp = *temp.keyvalue_temp = *temp.valueindex = index_tempvalue = value_temp// 执行 for-range 里面的代码// .....} 

map的遍历是无序的,同时不会指定次数,但是同样需要避免在遍历过程中,操作map。

2.5 chan

    for {index_temp, ok = <- chif !ok {break}index = index_temp// 执行 for-range 里面的代码// .....}

可以看到遍历chan,最终依然是使用操作符<-读取数据的,但是会对第二个值进行判断,所以可以保证for-range返回的值都是成功读取的值,当没有数据读取的时候,依然会因为操作符<-阻塞。

3. 总结

总的来说,for-range和java里面的for-each是类似的,原理都可以理解为语法糖,在编译的时候再进行替换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/434091.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

03-Redis缓存高可用集群

文章目录 1、Redis集群方案比较2、Redis高可用集群搭建redis集群搭建Java操作redis集群 4、Redis集群原理分析槽位定位算法跳转重定位Redis集群节点间的通信机制gossip通信的10000端口网络抖动 Redis集群选举原理分析集群脑裂数据丢失问题集群是否完整才能对外提供服务Redis集群…

【LeetCode每日一题】2865. 美丽塔 I

2024-1-24 文章目录 [2865. 美丽塔 I](https://leetcode.cn/problems/beautiful-towers-i/) 2865. 美丽塔 I 初始化变量 ans 为0&#xff0c;用于记录最大的和值。获取整数列表的长度&#xff0c;保存到变量 n 中。使用一个循环遍历列表中的每个位置&#xff0c;从0到n-1。在循…

【JavaEE】网络原理: 网络编程套接字(概念)

目录 1.什么是网络编程 2.网络编程中的基本概念 2.1发送端和接收端 2.2请求和响应 2.3客户端和服务端 3.Socket套接字 4.Socket编程注意事项 1.什么是网络编程 网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信 (…

【C++】类和对象(中篇)(全网最细!!!)

文章目录 &#x1f354;一、类的六个默认成员函数&#x1f354;二、构造函数&#x1f35f;1、概念&#x1f35f;2、特性&#x1f369;默认构造函数 &#x1f354;三、析构函数&#x1f35f;1、概念&#x1f35f;2、特性&#x1f369;默认析构函数 &#x1f354;四、拷贝构造函数…

STL之queue 【队列】

STL之queue 【队列】 一.基本用法1.头文件2.创建queue3.插入元素&#xff1a;4.删除元素(弹出元素)&#xff1a;5.访问队列的前端元素6.访问队列的后端元素7.检查队列是否为空8.获取队列的大小 二.综合示例&#xff1a;用C语言实现队列queue常见的应用场景包括&#xff1a; que…

Redis2-事务 连接Java 整合springboot 注解缓存

一、订阅和发布 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 Redis的发布和订阅 客户端订阅频道发布的消息 频道发布消息 订阅者就可以收到消息 发布订阅的代…

图像噪声、去噪基本方法合集(Python实现)

文章目录 前言 本文主要参考冈萨雷斯的数字图像处理 &#xff08;第4版&#xff09;&#xff0c;介绍图片中一些常见的噪声形式和常用的去噪方法&#xff0c;并且给出相应滤波方法的实现代码。 一、噪声分类 1、高斯噪声2、泊松噪声3、椒盐噪声4、瑞利噪声5、爱尔兰&#xff0…

基于 java+springboot+mybatis电影售票网站管理系统前台+后台设计和实现

基于 javaspringbootmybatis电影售票网站管理系统前台后台设计和实现 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承…

node12集成form-create遇到的问题

其他版本需要根据node版本以及npm调整 无法安装 taobao镜像出现问题 跟换为最新版本的 // 1. 清空缓存 npm cache clean --force // 2. 关闭SSL验证 npm config set strict-ssl false // 3. 切换新源 npm config set registry https://registry.npmmirror.com // 4. 查看源是…

5 步轻松上手,教你从 0 到 1 落地 Jmeter 接口自动化脚本!

Jmeter是进行接口测试的一款非常主流的工具&#xff0c;但绝大部分测试工程师&#xff0c;对于Jmeter接口测试脚本整理都是一知半解的。今天这篇文章&#xff0c;就以一个金融项目中接口为例&#xff0c;通过简单5步&#xff0c;教大家如何0代码编写Jmeter接口自动化脚本&#…

特征点匹配 harris

算法的核心是利用局部窗口在图像上进行移动&#xff0c;判断灰度是否发生较大的变化。如果窗口内的灰度值&#xff08;在梯度图上&#xff09;都有较大的变化&#xff0c;那么这个窗口所在区域就存在角点。 这样就可以将 Harris 角点检测算法分为以下三步&#xff1a; 当窗口…

Studio One 6 mac 6.5.2 激活版 数字音乐编曲创作

PreSonus Studio One是PreSonus出品的一款功能强大的音乐创作软件。主要为用户提供音乐创作、录音、编辑、制作等功能。它可以让你创造音乐&#xff0c;无限的轨道&#xff0c;无限的MIDI和乐器轨道&#xff0c;虚拟乐器和效果通道&#xff0c;这些都是强大和完美的。 软件下载…