Go 变量、常量与字符串:理解数值计算和中文长度
用一个学习进度示例掌握变量初始化、常量、浮点转换和格式化输出,并理解字符串字节数与Unicode码点数的区别。
本节目标
用一个学习进度示例掌握变量初始化、常量、浮点转换和格式化输出,并理解字符串字节数与Unicode码点数的区别。
前置知识
已完成第1篇,能够运行main.go。认识整数、字符串和基本算术即可。
准备与运行
在一个新的练习目录执行以下命令。目录名可以修改;若该目录已经初始化过模块,不要重复执行go mod init。
mkdir go-lesson-02
cd go-lesson-02
go mod init example.com/devcn/lesson02将下方完整代码保存为当前目录的main.go,然后执行:
go fmt ./...
go run .先用go version确认工具链可用。本例在Go 1.25.7、macOS ARM64环境验证,只使用标准库;没有测试所有操作系统和Go版本。
核心概念
变量可以在程序运行过程中赋新值,常量用于表达不随运行改变的值。本例用常量total表示计划总数,用变量completed表示已完成数量。函数内的:=同时声明并初始化变量;给已存在的单个变量改值,通常使用=。
计算完成比例时,操作数的类型决定除法行为。整数1除以整数4得到0,即使之后把这个结果转换为浮点数,也无法恢复丢掉的小数。因此必须先转换操作数,再计算比例。
Go字符串保存字节序列。对示例中的UTF-8文本“学习Go”,两个汉字各占3字节,两个英文字母各占1字节,所以len得到8。转换为rune切片后长度为4,表示4个码点。码点数量不等于所有文本中的视觉字符数量,组合音标和部分emoji需要更细致的处理。
完整示例
package main
import "fmt"
func main() {
const total = 4
completed := 1
label := "学习Go"
fmt.Println(len(label), len([]rune(label)))
fmt.Printf("%.0f%%\n", float64(completed)/float64(total)*100)
}运行后应得到:
8 4
25%代码如何工作
const total = 4为计算提供固定分母。completed := 1让编译器从初始值推断变量类型。随后第一行输出同时展示字节长度和码点数量,方便直接比较。
第二行先把两个整数转换成float64,再乘以100。%.0f表示显示浮点数但不保留小数位;%%输出百分号,\n负责换行。这里的格式只是显示方式,不会把变量本身变成整数。
在这个例子中,字符串没有被修改。字符串不可原地修改某个字节;如果要替换内容,可构造新字符串,或根据需求转换为可修改的字节、码点序列后再转换回来。
常见错误与边界
- 把表达式写成
float64(completed / total)会先发生整数除法,结果是0%。 completed = 2是赋值;在没有任何新变量的情况下重复写completed := 2会报错。- 不要把len(string)标成“中文字符数”,也不要把rune数量当作所有情况下的人眼字数。
- 总数如果来自输入,应先验证大于0,再计算比例。本例总数是固定常量4,不涉及动态零分母。
练习
把completed改成2,预测百分比;把label改成“Go入门”,预测字节长度和码点数。
参考答案
完成比例变为50%。字符串“Go入门”包含两个ASCII字母和两个汉字,因此输出仍为8和4。
可将main中的两行初始化替换为:
completed := 2
label := "Go入门"不要只看最终输出,还应尝试在转换前做整数除法,比较两个表达式为何得到不同结果。
文章回复
0 条公开回复