Go1.23 新特性:Slices、Panic、Cookie 等函數(shù)改進(jìn),效率提高了!
大家好,我是煎魚。
最近介紹了 Go1.23 的幾個(gè)重要新特性。今天給大家分享一些本次新版本的方法/函數(shù)的功能優(yōu)化、改進(jìn)的匯總。
主打一個(gè)快速知悉,跟上新用法??纯?rsc 在 Go 核心團(tuán)隊(duì)負(fù)責(zé)人的職業(yè)生涯最后都推動(dòng)了什么函數(shù)的合入。
Go1.23 方法/函數(shù)優(yōu)化
slices.Repeat
這是一個(gè)今年(2024 年)才提出的新提案,原提案作者提供給功能介紹時(shí),還給出了其他語(yǔ)言的相關(guān)案例。很快受到了 Go 官方團(tuán)隊(duì)的響應(yīng)并通過(guò)。
圖片
函數(shù)簽名:
func Repeat[S ~[]E, E any](x S, count int "S ~[]E, E any") S
Repeat 方法會(huì)返回一個(gè)新的切片,函數(shù)的作用是將所提供的切片,按給定的次數(shù)進(jìn)行重復(fù)。
注意:如果 count 為負(fù)數(shù)或溢出,該方法會(huì)觸發(fā) panic 事件。
Go1.23 代碼例子如下:
import (
"fmt"
"slices"
)
func main() {
s := []string{"煎魚", "咸魚", "摸魚"}
repeat := slices.Repeat(s, 2)
fmt.Println(repeat)
}
輸出結(jié)果:
[煎魚 咸魚 摸魚 煎魚 咸魚 摸魚]
os.DirFS
這個(gè)新提案由 rsc 于 2023 年從 2021 年的舊提案轉(zhuǎn)化過(guò)來(lái),目的上是為了更安全地將目標(biāo)文件復(fù)制到本地文件系統(tǒng),認(rèn)為可以幫助到很多場(chǎng)景。
圖片
函數(shù)簽名:
func DirFS(dir string) fs.FS
os.DirFS 方法返回以目錄 dir 為根的文件樹(shù)的文件系統(tǒng)(fs.FS),再結(jié)合 os.CopyFS 方法可以實(shí)現(xiàn)一次性的遞歸復(fù)制文件和目錄。
Go1.23 代碼例子如下:
src := os.DirFS("/Users/eddycjy/hello.txt")
dst := "/tmp/hello.txt"
err := os.CopyFS(dst, src)
if err != nil {
panic(err)
}
fmt.Printf("copied %s to %s\n", src, dst)
panic
在 Go1.22 及以前的版本,運(yùn)行以下代碼:
func main() {
panic("腦子\n進(jìn)\nI\n煎魚了")
}
輸出結(jié)果如下:
panic: 腦子
進(jìn)
I
煎魚了
goroutine 1 [running]:
main.main()
/tmp/sandbox3096848362/prog.go:6 +0x25
Go1.23 新版本起,輸出結(jié)果將會(huì)變成:
panic: 腦子
進(jìn)
I
煎魚了
goroutine 1 [running]:
main.main()
/tmp/sandbox1717599036/prog.go:6 +0x25
新版本后,panic 函數(shù)會(huì)用制表符縮進(jìn)錯(cuò)誤信息(如 panic 的參數(shù))的第二行和后續(xù)行,以區(qū)別于第一個(gè) goroutine 的堆棧跟蹤。
http.ParseCookie/ParseSetCookie
現(xiàn)在在 Go 程序中,如果我們要從 cookie 標(biāo)頭字符串中提取 cookie 結(jié)構(gòu)體。需要編寫以下類似的代碼:
req := http.Request{Header: http.Header{"Cookie": []string{raw}}}
cookies := req.Cookies()
雖然從原提案的角度來(lái)看還能用。但是終究繞了幾層才把東西取到,也不方便。
因此 @Eyal Posener 在 2018 年提出了 x/net/http/httpguts: add ParseCookie and ParseSetCookie[1] 的新提案訴求。在 2024 年,rsc 重新把這活拎了出來(lái),加進(jìn)了新版本中。
本次 Go1.23 是在 net.http 標(biāo)準(zhǔn)庫(kù)中新增了如下兩個(gè)方法:
- ParseCookie
- ParseSetCookie
ParseCookie
函數(shù)簽名:
func ParseCookie(line string) ([]*Cookie, error)
ParseCookie 解析 Cookie 標(biāo)頭值并返回其中設(shè)置的所有 Cookie。
Go1.23 代碼例子如下:
func main() {
lines := "session_id=eddycjy; value=hello-world; lang=en; lang=zh-CN"
cookies, _ := http.ParseCookie(lines)
for _, cookie := range cookies {
fmt.Printf("%s: %s\n", cookie.Name, cookie.Value)
}
}
輸出結(jié)果:
session_id: eddycjy
value: hello-world
lang: en
lang: zh-CN
如果存在多個(gè)相同字段,將會(huì)返回多次。
ParseSetCookie
函數(shù)簽名:
func ParseSetCookie(line string) (*Cookie, error)
ParseSetCookie 函數(shù)解析 Set-Cookie 標(biāo)頭值并返回 Cookie。
Go1.23 代碼例子如下:
func main() {
line := "session_id=eddycjy; MaxAge=0; lang=zh-CN; Domain=.eddycjy.com"
cookie, _ := http.ParseSetCookie(line)
fmt.Println("Name:", cookie.Name)
fmt.Println("Value:", cookie.Value)
fmt.Println("Domain:", cookie.Domain)
fmt.Println("MaxAge:", cookie.MaxAge)
}
輸出結(jié)果:
Name: session_id
Value: eddycjy
Domain: .eddycjy.com
MaxAge: 0
在解析結(jié)果上,主要是對(duì)標(biāo) Cookie,有預(yù)定義的標(biāo)準(zhǔn)字段:
type Cookie struct {
Name string
Value string
Path string // optional
Domain string // optional
Expires time.Time // optional
RawExpires string // for reading cookies only
// MaxAge=0 means no 'Max-Age' attribute specified.
// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
// MaxAge>0 means Max-Age attribute present and given in seconds
MaxAge int
Secure bool
HttpOnly bool
SameSite SameSite
Raw string
Unparsed []string // Raw text of unparsed attribute-value pairs
}
如果有自定義字段需要讀取的,可以使用 Cookie.Raw 讀取到原始的字符串進(jìn)行解析和額外處理。
總結(jié)
今天給大家分享了一些 Go1.23 新版本的新方法、函數(shù),目前來(lái)看這些函數(shù)沒(méi)有特別大的功能調(diào)整,主要都是對(duì)于日常工程開(kāi)發(fā)上的優(yōu)化。
這些新調(diào)整也算是針對(duì)開(kāi)發(fā)效率的一定的提效了,大家可以及時(shí)用到工作的開(kāi)發(fā)上!