讲师中心 微信公众号
AI工具推荐 视频效率加速

Go语言中字符串数组的字符遍历与UTF-8编码解析

梦墨酱_6361

梦墨酱_6361

发布时间:2025-12-04 17:00:09

|

938人浏览过

|

来源于php中文网

原创

Go语言中字符串数组的字符遍历与UTF-8编码解析

本教程旨在详细阐述go语言中如何正确遍历字符串数组并逐个打印其内部字符。文章将深入探讨go字符串的utf-8编码特性,区分字节(byte)与unicode码点(rune)的概念,并通过示例代码演示使用`for range`循环进行高效且准确的字符遍历,避免在处理多字节字符时出现乱码或错误。

理解Go语言中的字符串与字符

在Go语言中,字符串(string)是一个只读的字节切片,其内部通常采用UTF-8编码存储。这意味着一个Go字符串可以包含任意二进制数据,但通常我们将其视为文本。需要注意的是,一个“字符”在Go语言中通常指的是一个Unicode码点(rune),而不是一个字节(byte)。对于ASCII字符,一个码点占用一个字节;但对于非ASCII字符(如中文、日文等),一个码点可能占用2到4个字节。

许多初学者在尝试遍历字符串并打印单个字符时,可能会误将字符串当作字节数组直接索引,或在循环条件上出现混淆。例如,以下代码尝试遍历一个字符串切片,并期望打印每个字符串中的单个字符:

package main

import "fmt"

func main() {
    strslice := make([]string, 4, 5)
    strslice[0] = "hello"
    strslice[1] = "go"
    strslice[2] = "lang"
    strslice[3] = "whatsup"
    // 这是一个常见的错误示范
    for i := 0; i < len(strslice[i]); i++ { // 循环条件错误,且strslice[i]是字符串,不是单个字符
        fmt.Printf("slice is %c \n", strslice[i]) // %c 期望一个字符,但这里传入了字符串
    }
}

上述代码存在两个主要问题:

  1. for i := 0; i < len(strslice[i]); i++:外层循环的条件len(strslice[i])是错误的,它试图获取当前索引i处字符串的长度,而不是切片本身的长度。这会导致索引越界或循环提前结束。
  2. fmt.Printf("slice is %c \n", strslice[i]):%c格式化动词用于打印单个字符(rune),但strslice[i]是一个完整的字符串。这会导致编译错误或运行时恐慌。

正确遍历字符串数组并打印字符

为了正确地遍历字符串数组中的每个字符串,并进一步遍历每个字符串中的单个字符(Unicode码点),我们应该使用Go语言提供的for range循环。for range循环在遍历字符串时,会自动解码UTF-8序列,并按序返回每个Unicode码点(rune)。

立即学习“go语言免费学习笔记(深入)”;

以下是实现这一目标的正确方法:

package main

import "fmt"

func main() {
    strslice := make([]string, 5, 5)
    strslice[0] = "hello"
    strslice[1] = "go"
    strslice[2] = "lang"
    strslice[3] = "whatsup"
    strslice[4] = "Hello, 世界" // 包含多字节字符的示例

    // 遍历字符串切片中的每个字符串
    for _, s := range strslice {
        // 遍历当前字符串s中的每个Unicode码点(字符)
        for _, c := range s {
            fmt.Printf("%c ", c) // %c 正确打印单个字符
        }
        fmt.Printf("\n") // 每个字符串的字符打印完后换行
    }
}

代码解析:

  1. for _, s := range strslice:
    • 这是一个用于遍历切片strslice的标准for range循环。
    • _表示我们不关心当前元素的索引。
    • s会依次接收strslice中的每一个字符串元素。
  2. for _, c := range s:
    • 这是一个用于遍历字符串s的for range循环。
    • 当for range用于字符串时,它会按序返回字符串中每个Unicode码点(rune)及其在字符串中的起始字节索引。
    • _表示我们不关心当前字符的字节索引。
    • c会依次接收字符串s中的每一个rune类型的值,即单个字符。
  3. fmt.Printf("%c ", c):
    • %c格式化动词专门用于打印rune类型的值,即单个字符。
    • 在每个字符后添加一个空格,使输出更易读。
  4. fmt.Printf("\n"):
    • 在每个字符串的所有字符打印完毕后,打印一个换行符,以区分不同字符串的输出。

输出结果:

Go语言(Golang)1.26.0
Go语言(Golang)1.26.0

Go语言(Golang)1.26.0版本官方下载,版本号 1.26.0,适合旧项目维护、兼容性测试和指定版本开发环境搭建。

下载
h e l l o 
g o 
l a n g 
w h a t s u p 
H e l l o ,   世 界 

深入理解字节与字符(Rune)的区别

为了进一步强调Go字符串中字节和Unicode码点(字符)的区别,我们可以通过一个包含多字节字符的字符串进行演示。

package main

import "fmt"

func main() {
    str := "Hello, 世界"

    fmt.Println("按字节遍历:")
    // 遍历字符串的底层字节
    for i := 0; i < len(str); i++ {
        fmt.Printf("'%c' ", str[i]) // str[i] 获取的是第i个字节
    }
    fmt.Printf("\n")

    fmt.Println("按字符(Rune)遍历:")
    // 遍历字符串的Unicode码点
    for _, c := range str {
        fmt.Printf("'%c' ", c) // c 获取的是一个rune
    }
    fmt.Printf("\n")
}

代码解析:

  1. for i := 0; i < len(str); i++:

    • 这种循环方式是通过索引i来访问字符串str中的每个字节。
    • str[i]返回的是一个byte类型的值(uint8),代表字符串在内存中的第i个字节。
    • 当使用fmt.Printf("'%c' ", str[i])打印这些字节时,%c会尝试将每个字节解释为ASCII字符。对于单字节的ASCII字符,这没有问题。但对于多字节的UTF-8字符(如“世”和“界”),它会将一个字符拆分成多个字节进行打印,导致显示为乱码或不完整的字符。例如,“世”在UTF-8中由3个字节组成,单独打印这些字节时,它们无法被正确解析为“世”字。
  2. for _, c := range str:

    • 这种循环方式是Go语言处理字符串的推荐方式,它会正确地迭代字符串中的每一个Unicode码点(rune)。
    • c接收的是一个rune类型的值(int32),代表一个完整的Unicode字符。
    • fmt.Printf("'%c' ", c)能够正确地打印出完整的字符,无论它是单字节还是多字节。

输出结果:

按字节遍历:
'H' 'e' 'l' 'l' 'o' ',' ' ' 'ä' '¸' '' 'ç' '' '' 
按字符(Rune)遍历:
'H' 'e' 'l' 'l' 'o' ',' ' ' '世' '界' 

从输出可以看出,当按字节遍历时,包含中文“世界”的字符串被拆分成了多个不可读的字符(例如'ä' '¸' '' 'ç' '' '')。而按字符(rune)遍历时,则能正确地显示“世”和“界”。

总结与最佳实践

  • Go字符串是UTF-8编码的字节序列:理解这一点是处理Go字符串的关键。
  • 区分字节(byte)和字符(rune):byte是uint8的别名,代表一个8位的字节;rune是int32的别名,代表一个Unicode码点。一个rune可能由一个或多个byte组成。
  • 使用for range遍历字符串:当需要处理字符串中的单个字符(Unicode码点)时,始终优先使用for range循环。它会自动处理UTF-8解码,确保你获得的是完整的字符,而不是原始字节。
  • 使用%c格式化动词打印字符:在fmt.Printf中,使用%c来打印rune类型的值,以正确显示单个字符。

通过遵循这些原则,您可以有效地在Go语言中处理字符串和字符,尤其是在面对多语言或包含特殊字符的文本数据时,避免常见的编码和显示问题。

热门AI工具

更多
UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

5439

2023.08.02

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

648

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1009

2023.11.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1578

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2344

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

5844

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

5009

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

6734

2024.03.22

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

0

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn