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

《Go小技巧易错点100例》第三十八篇

本期分享:

1.new和make的区别

2.Go语言的string和byte


newmake的区别

在 Go 语言中,newmake 是两个用于内存分配的关键字,但它们的用途和行为有本质区别:

核心区别
特性new(T)make(T, args)
适用类型所有类型(值类型、引用类型)仅限 slicemapchannel
返回值*T(指向类型零值的指针)T(已初始化的类型本身)
初始化行为分配内存并置零(零值)分配内存 + 初始化底层结构
详细对比

new(T):

  • 作用:为类型 T 分配一块内存,返回指向该内存的指针。
  • 特点
    • 内存被置零(如 int0string"",结构体字段为各自零值)。
    • 返回 *T 类型,需通过指针访问值。
  • 示例
p := new(int)   // p 是 *int 类型,指向值为 0 的内存
fmt.Println(*p) // 输出 0

make(T, args):

  • 作用:为 slicemapchannel 分配内存并初始化底层结构。
  • 特点
    • 返回类型 T 本身(而非指针)。
    • slice 会初始化底层数组和长度/容量。
    • map 会初始化哈希表。
    • channel 会初始化缓冲区(如果指定)。
  • 示例
s := make([]int, 5)   // 创建长度为 5 的切片,底层数组已分配
m := make(map[string]int) // 创建空 map(已初始化哈希表)
ch := make(chan int, 10)  // 创建带缓冲的 channel
关键区别总结

内存分配 vs 初始化

  • new 仅分配内存并置零,不初始化复杂结构。
  • make 分配内存并完成类型特定的初始化(如切片底层数组、map 的哈希桶)。

返回值类型

  • new 返回指针,需通过 * 解引用。
  • make 返回类型本身,可直接使用。

适用场景

  • new 用于简单值类型或需要指针的场景。
  • make 专门用于 slice/map/channel 的初始化。
底层原理
  • new 调用 runtime.newobject 分配内存并置零。
  • make 调用类型特定的初始化函数(如 makeslicemakemap),完成底层数据结构的初始化。

理解这些区别可以避免内存操作错误,确保代码健壮性。

Go语言的string和byte

在 Go 语言中,string[]byte(字节切片)是紧密相关但功能不同的数据类型,它们的关系体现在底层存储、不可变性、编码规则和操作方式上。

底层本质:字符串是只读的字节序列**

string 的底层结构

Go 的 string 类型在底层是一个只读的字节切片struct { ptr *byte; len int }),直接指向一段连续的内存空间。例如:

s := "Hello"
// 底层表示为:ptr 指向字节数组 [72, 101, 108, 108, 111],len 为 5

[]byte 的底层结构

[]byte 是一个可变的字节切片,包含指向底层数组的指针、长度和容量。例如:

b := []byte{72, 101, 108, 108, 111}
// 底层表示为:ptr 指向字节数组,len 和 cap 均为 5
核心区别:不可变性 vs 可变性

string 的不可变性

Go 的字符串一旦创建,内容不可修改。任何修改操作(如拼接、替换)会生成新字符串:

s := "Hello"
// s[0] = 'h' // 编译错误:无法修改字符串
s = "h" + s[1:] // 合法:生成新字符串 "ello"

[]byte 的可变性

字节切片允许直接修改内容:

b := []byte{72, 101, 108, 108, 111}
b[0] = 104 // 修改后,b 变为 [104, 101, 108, 108, 111](即 "hello")
转换与性能影响

string[]byte

通过 []byte(s) 将字符串转为字节切片时,会复制底层数据(因为字符串不可变,需保证切片可独立修改):

s := "Hello"
b := []byte(s) // 复制 s 的字节到新切片
b[0] = 'h'     // 修改切片不影响原字符串

[]bytestring

通过 string(b) 将字节切片转为字符串时,也会复制数据(确保字符串不可变性):

b := []byte{72, 101, 108, 108, 111}
s := string(b) // 复制切片的字节到新字符串
编码与 Unicode 支持

默认 UTF-8 编码

Go 的 string 类型隐式支持 UTF-8,可直接存储多语言字符:

s := "你好" // UTF-8 编码为 3 字节/字符

[]byte 的原始字节

字节切片不关心编码,仅表示原始二进制数据。若需处理 Unicode 字符,需手动解码:

b := []byte{228, 189, 160, 229, 165, 189} // UTF-8 编码的 "你好"
s := string(b) // 正确还原为 "你好"
常见使用场景
场景使用 string使用 []byte
文本处理字符串拼接、正则表达式、格式化修改字符内容(需转 []byte
网络/文件 I/O发送/接收文本数据读写二进制协议(如 Protobuf)
加密/哈希极少直接使用操作原始字节数据
JSON 解析解析为 string 字段解析为 []byte 字段(需反序列化)
关键总结

底层共享string[]byte 均基于字节,但 string 是只读的,[]byte 是可变的。

转换代价:两者转换会复制数据,需避免高频操作。

编码处理string 默认 UTF-8,[]byte 是原始字节,需显式处理编码。

性能优化:对字符串的修改需通过 []byte 完成,或使用 strings.Builder 减少分配。

示例代码
package mainimport ("fmt""unicode/utf8"
)func main() {// string → []bytes := "Hello, 世界"b := []byte(s)b[7] = 0xE4 // 修改 "世" 的 UTF-8 字节(需谨慎处理编码)fmt.Println(string(b)) // 输出可能乱码(需正确处理 Unicode)// 处理 Unicode 字符r := []rune(s) // 将字符串转为 Unicode 码点切片r[7] = '新'    // 修改字符fmt.Println(string(r)) // 输出 "Hello, 新界"
}

理解 string[]byte 的关系,有助于高效处理文本与二进制数据,避免编码陷阱和性能问题。

本篇结束~


文章转载自:

http://ePuPj958.rkqqf.cn
http://6K14VXTQ.rkqqf.cn
http://m6RNLd5W.rkqqf.cn
http://pDAjm7vH.rkqqf.cn
http://JQ4L97nc.rkqqf.cn
http://apypKrcp.rkqqf.cn
http://curuQ4zs.rkqqf.cn
http://Qin0ni2b.rkqqf.cn
http://nZMzvd8g.rkqqf.cn
http://mxaGNB23.rkqqf.cn
http://t4ek4rsx.rkqqf.cn
http://k5N2grLm.rkqqf.cn
http://Cw3dzDJ4.rkqqf.cn
http://Lbb8wL6C.rkqqf.cn
http://fKfgWkoh.rkqqf.cn
http://sVTEfmD1.rkqqf.cn
http://W2kzyEQk.rkqqf.cn
http://P13Z3LH2.rkqqf.cn
http://I5hUfwXo.rkqqf.cn
http://AFsHov8L.rkqqf.cn
http://V9VcefIc.rkqqf.cn
http://L0ev7aiW.rkqqf.cn
http://9KQaOATe.rkqqf.cn
http://OK8iQ8J5.rkqqf.cn
http://9BKtPCSK.rkqqf.cn
http://EVk4OqCB.rkqqf.cn
http://2WbZoi9L.rkqqf.cn
http://BYEjudCS.rkqqf.cn
http://aKyZrgdg.rkqqf.cn
http://MsOGH93Z.rkqqf.cn
http://www.dtcms.com/a/372094.html

相关文章:

  • Conda 包管理器与环境管理使用指南
  • 笔记本、平板如何成为电脑拓展屏?向日葵16成为副屏功能一键实现
  • OpenHarmony 显示能效管理组件:掌控屏幕亮灭与亮度的核心利器
  • SQLite的基本操作
  • 第五课 C#语言基本元素概览,初始类型,变量与方法,算法简介
  • 【系统分析师】第12章-关键技术:软件架构设计(核心总结)
  • Lightdash:一个免费开源的自助式BI平台
  • Claude Code 使用教程
  • UML(统一建模语言)
  • Android开发-常用布局
  • Spring Cloud Gateway 进行集群化部署
  • EmbodiedOneVision——类似π0.5集成了离散自回归解码与连续流匹配去噪:单个模型中完成具身推理、动作生成
  • Paper reading - 03. Speech sequencing in the human precentral gyrus
  • Spring事务失效的常见陷阱与解决方案
  • 现代C++:现代C++?
  • ZSet
  • Linux初级篇
  • MySQL集群高可用架构——组复制 (MGR)
  • MySQL Cluster核心优缺点
  • RestTemplate使用 | RestTemplate设置http连接池参数
  • 01OpenCV简介
  • 美股市场股票数据API对接文档
  • Coze源码分析-资源库-删除插件-前端源码-核心接口与工具
  • 【深度学习】重采样(Resampling)
  • http接口幂等性
  • 无重复字符的最长子串
  • 架构思维:架构师视角的 FullGC 治理
  • pytest(1):fixture从入门到精通
  • Logstash中http_poller插件的用法
  • 软考中级习题与解答——第三章_操作系统(1)