当前位置: 首页 > article >正文

Go 语言 for 的用法

For statements

本文简单翻译了 Go 语言中 for 的三种用法,可快速学习 Go 语言 for 的使用方法,希望本文能为你解开一些关于 for 的疑惑。详细内容可见文档 For statements。

For statements with single condition

在最简单的形式中,只要 for 语句布尔条件结果为真,就重复执行代码块。在每次迭代之前都会评估该条件。如果条件不存在,则相当于布尔值 true。

for a < b {
	a *= 2
}

// 永远为真
for { }

For statements with for clause

带有 ForClause 的 for 语句也受其条件控制,但此外它还可以指定一个 init 和一个 post 语句,例如一个赋值语句、一个递增或递减语句。init 语句可以是一个短变量声明,但 post 语句不行。init 语句声明的变量的作用域在 for 代码块内部。

for i := 0; i < 10; i++ {
	f(i)
}

// 不能在外面使用变量 i

如果 init 语句不为空,则在第一次评估迭代条件前执行一次;post 语句在每次执行代码块后执行。ForClause 的任何元素都可以为空,但除非只有一个条件,否则分号不能省略。如果条件不存在,则相当于布尔值 true。

这种形式的 for 语句与 C++ 的 for 循环很相似。但有一点要注意的是,它只能有一个 post 语句,并且在 Go 中递增和递减是语句,这意味着我们不能在 post 语句中写出 i++, j-- 这样的代码。

例如,我们想验证一个字符串是否是回文串,用 C++ 可以这样写:

bool judge(string str) {
    for (int i = 0, j = str.size()-1; i < j; i++, j--) {
        if (str[i] != str[j]) {
            return false;
        }
    }
    return true;
}

在 Go 中,我们需要写成如下形式:

func judge(str string) bool {
    for i, j := 0, len(str)-1; i < j; {
        if str[i] != str[j] {
            return false
        }
        i++
        j--
    }
    return true
}

For statements with range clause

带有 range 子句的 for 语句会遍历数组、切片、字符串或 map 的所有条目,或者从 channel 接收的值。对于每个条目,它会将迭代值分配给相应的迭代变量(如果存在),然后执行代码块。

RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .

range 子句中右边的表达式称为范围表达式,其类型必须是数组、数组指针、切片、字符串、map 或允许接收操作的 channel。与赋值类似,左侧的操作数必须可寻址的或 map 索引表达式;它们表示迭代变量。如果范围表达式是 channel,则最多允许一个迭代变量,否则最多允许两个。

左侧的函数调用每次迭代都会计算一次。对于迭代,如果存在相应的迭代变量,则按如下方式生成迭代值:

范围表达式                            第一个值及类型   第二个值及类型

array or slice  a [n]E, *[n]E or []E index    int    a[i]       E
string          s string type        index    int    见下文      rune
map             m map[K]V            key      K      m[k]       V
channel         c chan E, <-chan E   element  E
  1. 对于数组、数组指针或切片值 a,索引迭代值从 0 开始按递增顺序生成。如果只有一个迭代变量,则只会生成从 0 到 len(a)-1 的整数值,并不会索引到数组或切片本身
  2. 对于字符串值,range 子句从 0 开始迭代字符串中的 Unicode 码点。在连续的迭代中,索引值将是字符串中连续 UTF-8-encoded 码点的第一个字节的索引;而第二个值,类型为 rune,是相应码点的值

UTF8 解码

  1. map 的迭代顺序未指定(底层实现是哈希表),并且不保证两次迭代的顺序相同
  2. 对于 channel,产生的迭代值是 channel 发送的连续值,直到 channel 关闭

迭代值被分配给各自的迭代变量,如赋值语句中一样。迭代变量可以通过 range 子句使用短变量声明(:=)的形式来声明。

需要注意的是对 string 的遍历,它并不是一个字节一个字节遍历的,它是以 Unicode 码点为单位遍历的。string 使用 UTF8 编码,使用 1 到 4 个字节来表示每个 Unicode 码点,ASCII 部分字符只使用 1 个字节,常用字符部分使用 2 或 3 个字节表示。

上面图片可以看到中文占了三个字节,图片出处为《Go 程序设计语言》第三章。

str := "Hello, 世界"
for i, r := range str {
    fmt.Printf("%d\t%q\n", i, r)
}

var key string
var val int
m := map[string]int{"mon": 0, "tue": 1, "wed": 2, "thu": 3, "fri": 4, "sat": 5, "sun": 6}
for key, val = range m {
    fmt.Println(key, " : ", val)
}

http://www.kler.cn/a/233730.html

相关文章:

  • 2024 年 8 个最佳 API 设计工具图文介绍
  • hadoop大数据平台
  • kafka消费数据太慢了,给优化下
  • LLMs之Code:Github Spark的简介、安装和使用方法、案例应用之详细攻略
  • Matlab自学笔记四十一:介绍日期时间型的显示格式:年‘y‘ 月‘M‘ 日‘d‘ 周‘e‘ 时‘h‘ 分‘m‘ 秒‘s‘
  • Vue常用加密方式
  • 《剑指 Offer》专项突破版 - 面试题 36 : 详解后缀表达式(C++ 实现)
  • 计算机毕业设计 | SSM超市进销存管理系统(附源码)
  • 鸿蒙原生应用再添新丁!央视新闻 入局鸿蒙
  • 24 SEMC相关
  • VSTO打包Word插件WPS也支持
  • Go语言每日一练——链表篇(四)
  • 自动化测试工具
  • WifiConfigStore初始化读取-Android13
  • 8868体育助力西甲皇家马德里俱乐部 帮助球队把握榜首大战
  • Days 27 ElfBoard 板 AltiumDesigner 相同电路快速布局布线
  • 【EEG信号处理】对信号进行模拟生成
  • C++自定义函数详解
  • ChatGLM2-6B模型的win10测试笔记
  • 设计模式-装饰模式 Decorator
  • 单片机学习笔记---蜂鸣器工作原理
  • M1 Mac使用SquareLine-Studio进行LVGL开发
  • 锐捷设备常用命令
  • JVM相关-JVM模型、垃圾回收、JVM调优
  • 解析十六进制雷达数据格式:解析雷达FSPEC数据
  • c语言内存对齐