admin管理员组文章数量:1440489
Go 1 正式发布时相比 r60.3 有哪些值得注意的改动?
本系列旨在梳理 Go 的 release notes 与发展史,来更加深入地理解 Go 语言设计的思路。
Go 1 值得关注的改动:
- 初始化时 goroutine 的启动时机:Go 1 允许在初始化过程中创建并运行 goroutine,不再限制其启动时机,增强了
init
构造的实用性。 rune
类型的引入:Go 1 引入rune
类型(int32
的别名)表示 Unicode 码点,为将来int
扩展到 64 位做准备。error
类型和errors
包:Go 1 将error
定义为内置接口,并引入errors
包,取代os.Error
,使错误处理更通用。- 不允许开发者对 map 的迭代顺序有依赖:Go 1 明确规定 map 的迭代顺序不可预测,禁止依赖特定顺序。
- 多重赋值的细化:Go 1 明确多重赋值时先从左到右求值所有表达式,再按顺序赋值,确保行为一致。
- 复制包含未导出字段的结构体:Go 1 允许复制包含其他包未导出字段的结构体,提升了 API 设计的灵活性。
- 相等性定义的调整:Go 1 为结构体和数组定义了相等性,可用作 map 键,同时移除函数和 map 的相等性定义(nil 比较除外)。
下面是一些值得展开的讨论:
rune
类型的引入
简要概括
Go 1 引入 rune
类型(int32
的别名)表示 Unicode 码点,为 int
扩展到 64 位做准备,同时优化字符存储。
详细内容
在 Go 1 之前,int
在所有平台上均为 32 位,这在 64 位平台上限制了其表示能力,尤其是在索引大数组时。若直接将 int
扩展为 64 位,会因 Unicode 码点的存储浪费空间。为此,Go 1 引入 rune
类型,作为 int32
的别名,专门表示 Unicode 码点。字符字面量如 'a'
、'語'
和 '\u0345'
的默认类型变为 rune
,类似于 1.0
默认类型为 float64
。未显式指定类型的字符常量变量将具有 rune
类型。标准库中的函数,如 unicode.ToLower
,也更新为接受和返回 rune
类型。
以下是一个示例:
代码语言:go复制delta := 'δ' // delta 的类型为 rune
var DELTA rune
DELTA = unicode.ToUpper(delta)
epsilon := unicode.ToLower(DELTA + 1)
if epsilon != 'δ'+1 {
log.Fatal("inconsistent casing for Greek")
}
更新影响:由于类型推断(type inference)会自动引入 rune
,大多数代码不受影响。少数代码可能需添加简单的类型转换以解决类型错误。
error
类型和 errors
包
简要概括
Go 1 将 error
定义为内置接口,并引入 errors
包,取代 os.Error
和 os.NewError
,使错误处理更通用和灵活。
详细内容
在 Go 1 之前,os.Error
位于 os
包中,这源于历史原因,但其局限性逐渐显现:错误处理比操作系统更基础,且在 syscall
等包中使用 os.Error
会引入不必要的依赖。Go 1 通过内置 error
接口解决此问题:
type error interface {
Error() string
}
同时引入 errors
包,提供 New
函数创建错误:
func New(text string) error
fmt
包会自动调用 Error
方法打印错误值。开发者可自定义错误类型,只需实现 Error
方法:
type SyntaxError struct {
File string
Line int
Message string
}
func (se *SyntaxError) Error() string {
return fmt.Sprintf("%s:%d: %s", se.File, se.Line, se.Message)
}
此外,syscall
包现在返回 error
类型。在 Unix 平台上,系统调用错误由 syscall.Errno
实现,满足 error
接口。
更新影响:运行 go fix
可更新大部分代码。若错误类型定义了 String
方法,需手动改为 Error
方法。建议使用 os
包而非 syscall
以减少影响。
map 迭代顺序不可预测
简要概括
Go 1 明确规定 map 的迭代顺序不可预测,禁止开发者依赖特定顺序,以提升 map 实现的灵活性。
详细内容
在 Go 1 之前,map 的迭代顺序未在语言规范中定义,且因硬件平台不同而异,导致测试不稳定。Go 1 使用 for range
迭代 map 时,元素访问顺序被定义为不可预测,即使同一 map 多次运行也如此。代码不应假设元素按特定顺序访问:
m := map[string]int{"Sunday": 0, "Monday": 1}
for name, value := range m {
// 此循环不应假设 Sunday 先被访问
f(name, value)
}
此更改确保依赖顺序的代码尽早失败并修复,同时允许 map 实现优化性能和平衡性。
更新影响:工具无法自动修复,需手动检查所有 map 的 range
语句,确保不依赖迭代顺序。标准库中相关代码已修复。之前依赖未定义顺序的代码本就错误,此更改仅明确了不可预测性。
多重赋值的细化
简要概括
Go 1 明确多重赋值时先从左到右求值所有表达式,再按顺序赋值,确保行为可预测。
详细内容
语言规范长期保证赋值时先求值右侧表达式,再赋值给左侧。Go 1 进一步细化:若左侧包含需求值的表达式(如函数调用或数组索引),这些表达式按从左到右顺序求值,然后再赋值:
代码语言:go复制sa := []int{1, 2, 3}
i := 0
i, sa[i] = 1, 2 // 设置 i = 1, sa[0] = 2
sb := []int{1, 2, 3}
j := 0
sb[j], j = 2, 1 // 设置 sb[0] = 2, j = 1
sc := []int{1, 2, 3}
sc[0], sc[0] = 1, 2 // 先设置 sc[0] = 1,再设置为 2
更新影响:工具无法自动修复,但影响甚微。标准库代码未受影响,依赖之前未定义行为的代码本就错误。
复制包含未导出字段的结构体
简要概括
Go 1 允许复制包含其他包未导出字段的结构体,增强了 API 设计的灵活性。
详细内容
在 Go 1 之前,语言禁止复制包含其他包未导出字段的结构体,但方法接收者和 copy
、append
函数未受此限。Go 1 放宽限制,允许复制此类结构体,使包可返回不透明值而无需指针或接口,如 time.Time
和 reflect.Value
:
// 包 p 的定义
type Struct struct {
Public int
secret int
}
func NewStruct(a int) Struct { // 返回值类型为 Struct 而非 *Struct
return Struct{a, f(a)}
}
func (s Struct) String() string {
return fmt.Sprintf("{%d (secret %d)}", s.Public, s.secret)
}
// 导入 p 包的代码
import "p"
myStruct := p.NewStruct(23)
copyOfMyStruct := myStruct
fmt.Println(myStruct, copyOfMyStruct)
更新影响:此为新特性,现有代码无需更改。
相等性定义的调整
简要概括
Go 1 为结构体和数组定义了相等性,可用作 map 键,同时移除函数和 map 的相等性(nil 比较除外)。
详细内容
在 Go 1 之前,结构体和数组的相等性未定义,无法用作 map 键,而函数和 map 的相等性定义存在问题。Go 1 引入结构体和数组的相等性(==
和 !=
),采用逐元素比较:
type Day struct {
long string
short string
}
Christmas := Day{"Christmas", "XMas"}
Thanksgiving := Day{"Thanksgiving", "Turkey"}
holiday := map[Day]bool{
Christmas: true,
Thanksgiving: true,
}
fmt.Printf("Christmas is a holiday: %t\n", holiday[Christmas])
函数相等性(nil 比较除外)和 map 相等性被移除,因其定义复杂且不符合用户期望。slice 的相等性仍未定义。
更新影响:结构体和数组相等性为新特性,现有代码无需更改。依赖函数或 map 相等性的代码需手动修复。
本文标签: Go 1 正式发布时相比 r603 有哪些值得注意的改动
版权声明:本文标题:Go 1 正式发布时相比 r60.3 有哪些值得注意的改动? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/biancheng/1747742978a2752644.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论