自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 1.16 相比 Go 1.15 有哪些值得注意的改動(dòng)?

開(kāi)發(fā) 前端
Go 1.16 通過(guò)引入 ??io/fs?? 接口,推動(dòng)了文件系統(tǒng)操作的標(biāo)準(zhǔn)化和解耦 。這使得代碼可以更靈活地處理不同來(lái)源的文件數(shù)據(jù),無(wú)論是來(lái)自操作系統(tǒng)、內(nèi)存、嵌入資源還是壓縮包。

https://go.dev/doc/go1.16

Go 1.16 在 Go 1.15 的基礎(chǔ)上帶來(lái)了不少重要的更新和改進(jìn)。以下是一些值得關(guān)注的改動(dòng)要點(diǎn):

  • 平臺(tái)支持 (Ports) :新增對(duì) macOS ARM64(Apple Silicon)的原生支持 (GOOS=darwinGOARCH=arm64);原 darwin/arm64 (iOS) 重命名為 ios/arm64;新增 ios/amd64 以支持在 AMD64 macOS 上運(yùn)行的 iOS 模擬器;Go 1.16 是支持 macOS 10.12 Sierra 的最后一個(gè)版本。
  • 模塊 (Modules) :GO111MODULE 環(huán)境變量默認(rèn)為 on,即默認(rèn)啟用模塊感知模式;go build 和 go test 默認(rèn)不再修改 go.mod/go.sum 文件;go install 支持版本后綴,成為推薦的安裝方式;新增 retract 指令用于撤回版本。
  • go test :測(cè)試函數(shù)中調(diào)用 os.Exit(0) 現(xiàn)在會(huì)被視為測(cè)試失敗,但 TestMain 中的調(diào)用仍視為成功;同時(shí)使用 -c 或 -i 標(biāo)志與無(wú)法識(shí)別的標(biāo)志時(shí)會(huì)報(bào)錯(cuò)。
  • vet 工具 :新增一項(xiàng)檢查,用于警告在測(cè)試創(chuàng)建的 goroutine 中無(wú)效調(diào)用 testing.T 的 Fatal、Fatalf、FailNow 及 Skip 系列方法的情況。
  • 工具鏈 (Toolchain) :編譯器支持內(nèi)聯(lián)包含非標(biāo)簽 for 循環(huán)、方法值和類型選擇 (type switch) 的函數(shù);鏈接器性能得到提升(速度加快 20-25%,內(nèi)存減少 5-15%),適用于所有支持的平臺(tái),并能生成更小的二進(jìn)制文件;Windows 下 go build -buildmode=c-shared 默認(rèn)啟用 ASLR。
  • 文件嵌入 (Embedded Files) :新增 embed 包和 //go:embed 指令,允許在編譯時(shí)將靜態(tài)文件或文件樹(shù)嵌入到可執(zhí)行文件中。
  • 文件系統(tǒng) (File Systems) :新增 io/fs 包和 fs.FS 接口,為只讀文件樹(shù)提供了統(tǒng)一的抽象;標(biāo)準(zhǔn)庫(kù)多處已適配此接口;io/ioutil 包被棄用,其功能已遷移至 io 和 os 包。

下面是一些值得展開(kāi)的討論:

模塊系統(tǒng)的重要改進(jìn)和理念轉(zhuǎn)變

Go 1.16 對(duì)模塊系統(tǒng)進(jìn)行了多項(xiàng)重要調(diào)整,標(biāo)志著 Go 模塊化開(kāi)發(fā)的進(jìn)一步成熟和規(guī)范化。核心變化在于 默認(rèn)啟用模塊感知模式 并 強(qiáng)化了依賴管理的確定性 。

GO111MODULE 環(huán)境變量的默認(rèn)值從 auto 改為 on,這意味著無(wú)論當(dāng)前目錄或父目錄是否存在 go.mod 文件,go 命令都會(huì)默認(rèn)以模塊感知模式運(yùn)行。這一改變推動(dòng)開(kāi)發(fā)者全面擁抱 Modules,簡(jiǎn)化了環(huán)境配置。如果需要舊的行為,可以顯式設(shè)置 GO111MODULE=auto。

另一個(gè)關(guān)鍵變化是,go build 和 go test 等構(gòu)建命令 默認(rèn)不再自動(dòng)修改 go.mod 和 go.sum 文件 。如果構(gòu)建過(guò)程中發(fā)現(xiàn)需要添加或更新依賴、校驗(yàn)和,命令會(huì)報(bào)錯(cuò)退出(行為類似添加了 -mod=readonly 標(biāo)志)。Go 團(tuán)隊(duì)希望開(kāi)發(fā)者能更 顯式地管理依賴 ,推薦使用 go mod tidy 來(lái)整理依賴關(guān)系,或使用 go get 來(lái)獲取特定依賴。這有助于避免無(wú)意中修改依賴,增強(qiáng)了構(gòu)建的 可復(fù)現(xiàn)性 (reproducibility) 。

go install 命令得到了增強(qiáng),現(xiàn)在可以直接指定版本后綴來(lái)安裝可執(zhí)行文件,例如 go install example.com/cmd@v1.0.0。這種方式會(huì)在模塊感知模式下進(jìn)行構(gòu)建和安裝,并且 忽略當(dāng)前項(xiàng)目的 go.mod 文件 。這使得安裝 Go 工具變得非常方便,不會(huì)影響當(dāng)前工作項(xiàng)目的依賴。官方明確推薦 使用 go install(無(wú)論帶不帶版本后綴)作為模塊模式下構(gòu)建和安裝包的主要方式 。

相應(yīng)地,使用 go get 來(lái)構(gòu)建和安裝包的方式 已被棄用 。go get 未來(lái)將專注于 依賴管理 ,推薦配合 -d 標(biāo)志使用(僅下載代碼,不構(gòu)建安裝)。在未來(lái)的版本中,-d 可能會(huì)成為 go get 的默認(rèn)行為。

go.mod 文件新增了 retract 指令。模塊作者可以在發(fā)現(xiàn)已發(fā)布的版本存在嚴(yán)重問(wèn)題或系誤發(fā)布時(shí),使用該指令聲明撤回特定版本。其他項(xiàng)目在解析依賴時(shí)會(huì)跳過(guò)被撤回的版本,有助于防止問(wèn)題版本的擴(kuò)散。

此外,go mod vendor 和 go mod tidy 支持了 -e 標(biāo)志,允許在解析某些包出錯(cuò)時(shí)繼續(xù)執(zhí)行。Go 命令現(xiàn)在會(huì)忽略主模塊 go.mod 中被 exclude 指令排除的版本,而不是像以前那樣選擇下一個(gè)更高的版本,這進(jìn)一步增強(qiáng)了構(gòu)建的確定性。

最后,go get 的 -insecure 標(biāo)志被棄用,推薦使用 GOINSECUREGOPRIVATE 或 GONOSUMDB 環(huán)境變量進(jìn)行更細(xì)粒度的控制。go get example.com/mod@patch 的行為也發(fā)生變化,現(xiàn)在要求 example.com/mod 必須已存在于主模塊的依賴中。

這些變化體現(xiàn)了 Go 語(yǔ)言對(duì)依賴管理 規(guī)范化、顯式化、可復(fù)現(xiàn)性 的追求。開(kāi)發(fā)者應(yīng)適應(yīng)這些變化,使用 go mod tidy 和 go get -d 管理依賴,使用 go install cmd@version 安裝工具,并了解 retract 等新特性來(lái)更好地維護(hù)自己的模塊。

Vet 新增對(duì)測(cè)試中 Goroutine 內(nèi)誤用 Fatal/Skip 的警告

Go 1.16 的 vet 工具增加了一項(xiàng)新的檢查,旨在發(fā)現(xiàn)單元測(cè)試和基準(zhǔn)測(cè)試 (benchmark) 中一個(gè)常見(jiàn)的錯(cuò)誤模式:在測(cè)試函數(shù)啟動(dòng)的 goroutine 內(nèi)部調(diào)用 testing.T 或 testing.B 的 FatalFatalf、FailNow 或 Skip 系列方法。

為什么這是錯(cuò)誤的?

t.Fatal (及其類似方法) 的設(shè)計(jì)意圖是 立即終止當(dāng)前運(yùn)行的測(cè)試函數(shù) ,并將該測(cè)試標(biāo)記為失敗。然而,當(dāng)你在一個(gè)由測(cè)試函數(shù)創(chuàng)建的新 goroutine 中調(diào)用 t.Fatal 時(shí),它只會(huì)終止 這個(gè)新創(chuàng)建的 goroutine ,而 不會(huì)終止 原本的 TestXxx 或 BenchmarkXxx 函數(shù)。這會(huì)導(dǎo)致測(cè)試函數(shù)本身繼續(xù)執(zhí)行,可能掩蓋了真實(shí)的失敗情況,或者導(dǎo)致測(cè)試結(jié)果不可靠。

錯(cuò)誤示例:

假設(shè)我們有一個(gè)測(cè)試,需要在后臺(tái)檢查某個(gè)條件,如果條件不滿足則標(biāo)記測(cè)試失敗。

package main

import (
 "testing"
 "time"
)

func checkConditionInBackground() bool {
 time.Sleep(50 * time.Millisecond) // 模擬耗時(shí)操作
 return false // 假設(shè)條件不滿足
}

// 錯(cuò)誤的用法
func TestMyFeatureIncorrect(t *testing.T) {
 t.Log("Test started")
 go func() {
  t.Log("Goroutine started")
  if !checkConditionInBackground() {
   // 錯(cuò)誤:這只會(huì)終止 goroutine,不會(huì)終止 TestMyFeatureIncorrect
   // 測(cè)試會(huì)繼續(xù)執(zhí)行并最終(錯(cuò)誤地)報(bào)告為成功
   t.Fatal("Background condition check failed!")
  }
  t.Log("Goroutine finished check successfully") // 這行不會(huì)執(zhí)行
 }()

 // 主測(cè)試 goroutine 繼續(xù)執(zhí)行
 time.Sleep(100 * time.Millisecond) // 等待 goroutine 執(zhí)行(實(shí)踐中通常用 sync.WaitGroup)
 t.Log("Test finished")             // 這行會(huì)執(zhí)行,測(cè)試最終會(huì)顯示 PASSED
}

在這個(gè)錯(cuò)誤例子中,當(dāng) goroutine 中的 t.Fatal 被調(diào)用時(shí),只有這個(gè)匿名 func 的 goroutine 被終止了。TestMyFeatureIncorrect 函數(shù)本身并不知道后臺(tái)發(fā)生了錯(cuò)誤,它會(huì)繼續(xù)執(zhí)行,直到完成,測(cè)試結(jié)果會(huì)被標(biāo)記為 PASS,這顯然不是我們期望的。Go 1.16 的 vet 工具現(xiàn)在會(huì)對(duì)此類用法發(fā)出警告。

正確的做法:

正確的做法是,在 goroutine 中發(fā)現(xiàn)錯(cuò)誤時(shí),應(yīng)該使用 t.Error 或 t.Errorf 來(lái) 記錄錯(cuò)誤 ,然后通過(guò)其他方式(例如 return 語(yǔ)句) 安全地退出 goroutine 。主測(cè)試 goroutine 需要有一種機(jī)制(通常是 sync.WaitGroup)來(lái)等待所有子 goroutine 完成,并檢查是否記錄了任何錯(cuò)誤。

package main

import (
 "sync"
 "testing"
 "time"
)

func checkConditionInBackgroundCorrect() bool {
 time.Sleep(50 * time.Millisecond)
 return false
}

// 正確的用法
func TestMyFeatureCorrect(t *testing.T) {
 t.Log("Test started")
 var wg sync.WaitGroup
 wg.Add(1)

 go func() {
  defer wg.Done() // 確保 WaitGroup 被正確處理
  t.Log("Goroutine started")
  if !checkConditionInBackgroundCorrect() {
   // 正確:記錄錯(cuò)誤,然后正常退出 goroutine
   t.Error("Background condition check failed!")
   return // 退出 goroutine
  }
  t.Log("Goroutine finished check successfully")
 }()

 t.Log("Waiting for goroutine...")
 wg.Wait() // 等待 goroutine 執(zhí)行完畢
 t.Log("Test finished")
 // t.Error 會(huì)將測(cè)試標(biāo)記為失敗,所以無(wú)需額外操作
 // 測(cè)試最終會(huì)顯示 FAILED
}

在這個(gè)修正后的例子中,goroutine 使用 t.Error 記錄失敗信息,然后通過(guò) return 退出。主測(cè)試函數(shù)使用 sync.WaitGroup 等待 goroutine 完成。因?yàn)?nbsp;t.Error 被調(diào)用過(guò),整個(gè) TestMyFeatureCorrect 測(cè)試最終會(huì)被標(biāo)記為 FAIL,這準(zhǔn)確地反映了測(cè)試的實(shí)際結(jié)果。

開(kāi)發(fā)者在編寫并發(fā)測(cè)試時(shí),應(yīng)牢記 t.Fatal 等方法的行為,確保它們只在運(yùn)行測(cè)試函數(shù)的主 goroutine 中被調(diào)用。對(duì)于子 goroutine 中的失敗情況,應(yīng)使用 t.Error 或 t.Errorf 記錄,并配合同步機(jī)制確保主測(cè)試函數(shù)能感知到這些失敗。

使用 embed 包嵌入靜態(tài)文件

Go 1.16 引入了一個(gè)內(nèi)置的核心特性:文件嵌入。通過(guò)新的 embed 包和 //go:embed 編譯器指令,開(kāi)發(fā)者可以將靜態(tài)資源文件(如 HTML 模板、配置文件、圖片等)直接 編譯進(jìn) Go 可執(zhí)行文件中 。

為什么需要文件嵌入?

在 Go 1.16 之前,分發(fā)包含靜態(tài)資源的 Go 應(yīng)用通常需要將可執(zhí)行文件和資源文件一起打包。這增加了部署的復(fù)雜性,容易因文件丟失或路徑錯(cuò)誤導(dǎo)致程序失敗。文件嵌入解決了這個(gè)問(wèn)題,它使得 Go 應(yīng)用可以 編譯成一個(gè)完全獨(dú)立的、包含所有必需資源的單個(gè)可執(zhí)行文件 ,極大地簡(jiǎn)化了分發(fā)和部署過(guò)程。

如何使用?

核心是 //go:embed 指令,它必須緊跟在一個(gè) import 塊之后,或者在包級(jí)別的變量聲明之上。該指令告訴編譯器將指定的文件或目錄內(nèi)容嵌入到后續(xù)聲明的變量中。變量的類型決定了嵌入的方式:

  • 嵌入單個(gè)文件到 string
package main

import (
    _ "embed" // 需要導(dǎo)入 embed 包,即使只用 //go:embed
    "fmt"
)

//go:embed message.txt
var message string

func main() {
    fmt.Print(message)
}

假設(shè)同目錄下有一個(gè) message.txt 文件,內(nèi)容為 "Hello, Embed!"。編譯運(yùn)行后,程序會(huì)打印該文件的內(nèi)容。

  • 嵌入單個(gè)文件到 []byte
package main

import (
    _ "embed"
    "fmt"
)

//go:embed banner.txt
var banner []byte

func main() {
    fmt.Printf("Banner:\n%s", banner)
}

這對(duì)于嵌入非文本文件(如圖片)或需要處理原始字節(jié)的場(chǎng)景很有用。[]byte 是只讀的。

  • 嵌入文件或目錄到 embed.FS

這是最靈活的方式,可以將單個(gè)文件、多個(gè)文件或整個(gè)目錄樹(shù)嵌入到一個(gè)符合 io/fs.FS 接口的文件系統(tǒng)中。

假設(shè)有如下目錄結(jié)構(gòu):

.
├── main.go
└── static/
    ├── index.html
    └── css/
        └── style.css
package main

import (
    "embed" // 需要顯式導(dǎo)入 embed 包
    "fmt"
    "io/fs"
    "net/http"
)

//go:embed static/*
// 或者 //go:embed static/index.html static/css/style.css
// 或者 //go:embed static
var staticFiles embed.FS

func main() {
    // 讀取單個(gè)文件
    htmlContent, err := staticFiles.ReadFile("static/index.html")
    if err != nil {
        panic(err)
    }
    fmt.Println("Index HTML:", string(htmlContent))

    cssContent, err := fs.ReadFile(staticFiles, "static/css/style.css") // 也可以用 io/fs.ReadFile
    if err != nil {
        panic(err)
    }
    fmt.Println("CSS:", string(cssContent))

    // 將嵌入的文件系統(tǒng)作為 HTTP 文件服務(wù)器
    // 需要去除路徑前綴 "static/"
    httpFS, err := fs.Sub(staticFiles, "static")
    if err != nil {
        panic(err)
    }
    http.Handle("/", http.FileServer(http.FS(httpFS))) // 使用 http.FS 轉(zhuǎn)換
    fmt.Println("Serving embedded files on :8080")
    http.ListenAndServe(":8080", nil)
}

//go:embed static/* 或 //go:embed static 會(huì)將 static 目錄及其所有子目錄和文件嵌入到 staticFiles 變量中。這個(gè) embed.FS 類型的變量可以像普通文件系統(tǒng)一樣被訪問(wèn),例如使用 ReadFile 讀取文件內(nèi)容,或者配合 net/http、html/template 等包使用。

重要細(xì)節(jié):

  • //go:embed 指令后的路徑是相對(duì)于 包含該指令的源文件 的目錄。
  • 嵌入的文件內(nèi)容在編譯時(shí)確定,運(yùn)行時(shí)是 只讀 的。
  • 使用 embed.FS 時(shí),需要導(dǎo)入 embed 包。如果僅嵌入到 string 或 []byte,理論上只需 import _ "embed" 來(lái)激活編譯器的嵌入功能,但顯式導(dǎo)入 embed 通常更清晰。
  • embed.FS 實(shí)現(xiàn)了 io/fs.FS 接口,可以與 Go 1.16 中引入的新的文件系統(tǒng)抽象無(wú)縫集成。

文件嵌入是 Go 1.16 中一個(gè)非常實(shí)用的新特性,它簡(jiǎn)化了資源管理和應(yīng)用部署,使得創(chuàng)建單體、自包含的 Go 應(yīng)用變得更加容易。

新的文件系統(tǒng)接口 io/fs 與 io/ioutil 的棄用

Go 1.16 引入了新的 io/fs 包,其核心是定義了一個(gè) 標(biāo)準(zhǔn)的文件系統(tǒng)接口 fs.FS 。這個(gè)接口提供了一個(gè) 統(tǒng)一的、只讀的 文件系統(tǒng)訪問(wèn)抽象。同時(shí),長(zhǎng)期以來(lái)包羅萬(wàn)象但定義模糊的 io/ioutil 包被正式 棄用 。

為什么引入 io/fs?

在 Go 1.16 之前,Go 標(biāo)準(zhǔn)庫(kù)中操作文件系統(tǒng)的代碼(如 os 包、net/http 包中的文件服務(wù)、html/template 包的模板加載等)通常直接依賴于操作系統(tǒng)的文件系統(tǒng)。這導(dǎo)致代碼與底層實(shí)現(xiàn)耦合緊密,難以對(duì)不同類型的文件系統(tǒng)(如內(nèi)存文件系統(tǒng)、zip 文件、嵌入式文件等)進(jìn)行統(tǒng)一處理和測(cè)試。

io/fs 包的出現(xiàn)解決了這個(gè)問(wèn)題。它定義了簡(jiǎn)潔的 fs.FS 接口,核心方法是 Open(name string) (fs.File, error)。任何實(shí)現(xiàn)了這個(gè)接口的類型,都可以被看作是一個(gè)文件系統(tǒng),可以被各種期望使用 fs.FS 的標(biāo)準(zhǔn)庫(kù)或第三方庫(kù)消費(fèi)。

fs.FS 的實(shí)現(xiàn)者 (Producers):

  • embed.FS :Go 1.16 新增的 embed 包提供的類型,用于訪問(wèn)編譯時(shí)嵌入的文件。
  • os.DirFS(dir string) :os 包新增的函數(shù),返回一個(gè)基于操作系統(tǒng)真實(shí)目錄的 fs.FS 實(shí)現(xiàn)。
package main

import (
 "fmt"
 "io/fs"
 "os"
)

func main() {
 // 使用當(dāng)前目錄創(chuàng)建一個(gè) fs.FS
 fileSystem := os.DirFS(".")
 // 使用 fs.ReadFile 讀取文件 (需要 Go 1.16+)
 content, err := fs.ReadFile(fileSystem, "go.mod") // 讀取當(dāng)前目錄的 go.mod
 if err != nil {
  if os.IsNotExist(err) {
   fmt.Println("go.mod not found in current directory.")
  } else {
   panic(err)
  }
 } else {
  fmt.Printf("go.mod content:\n%s\n", content)
 }
}
  • zip.Reader :archive/zip 包中的 Reader 類型現(xiàn)在也實(shí)現(xiàn)了 fs.FS,可以直接訪問(wèn) zip 壓縮包內(nèi)的文件。
  • testing/fstest.MapFS :這是一個(gè)用于測(cè)試的內(nèi)存文件系統(tǒng)實(shí)現(xiàn),方便編寫依賴 fs.FS 的代碼的單元測(cè)試。

fs.FS 的消費(fèi)者 (Consumers):

  • net/http.FS() :http 包新增的函數(shù),可以將一個(gè) fs.FS 包裝成 http.FileSystem,用于 http.FileServer。
package main

import (
    "embed"
    "io/fs"
    "net/http"
)

//go:embed assets
var embeddedAssets embed.FS

func main() {
    // 假設(shè) assets 目錄包含 index.html 等靜態(tài)文件
    // 從 embed.FS 創(chuàng)建子文件系統(tǒng),去除 "assets" 前綴
    assetsFS, _ := fs.Sub(embeddedAssets, "assets")

    // 將 fs.FS 轉(zhuǎn)換為 http.FileSystem
    httpFS := http.FS(assetsFS)

    // 創(chuàng)建文件服務(wù)器
    http.Handle("/", http.FileServer(httpFS))
    http.ListenAndServe(":8080", nil)
}
  • html/template.ParseFS() / text/template.ParseFS() :模板包新增的函數(shù),可以直接從 fs.FS 中加載和解析模板文件。
package main

import (
    "embed"
    "html/template"
    "os"
)

//go:embed templates/*.tmpl
var templateFS embed.FS

func main() {
    // 從 embed.FS 加載所有 .tmpl 文件
    tmpl, err := template.ParseFS(templateFS, "templates/*.tmpl")
    if err != nil {
        panic(err)
    }
    // 執(zhí)行模板...
    tmpl.ExecuteTemplate(os.Stdout, "hello.tmpl", "World")
}
  • fs.WalkDir() / fs.ReadFile() / fs.Stat() :io/fs 包自身也提供了一些通用的輔助函數(shù),用于在任何 fs.FS 實(shí)現(xiàn)上進(jìn)行文件遍歷、讀取和獲取元信息。

io/ioutil 的棄用:

io/ioutil 包長(zhǎng)期以來(lái)包含了一些方便但功能分散的函數(shù),如 ReadFileWriteFileReadDirNopCloserDiscard 等。這些功能與其他標(biāo)準(zhǔn)庫(kù)包(主要是 io 和 os)的功能有所重疊或關(guān)聯(lián)。為了使標(biāo)準(zhǔn)庫(kù)的結(jié)構(gòu)更清晰、職責(zé)更分明,Go 團(tuán)隊(duì)決定 棄用 io/ioutil 包 。

io/ioutil 包本身 仍然存在且功能不變 ,以保證向后兼容。但是,官方 不鼓勵(lì)在新代碼中使用它 。其包含的所有功能都已遷移到更合適的包中:

  • ioutil.ReadFile -> os.ReadFile
  • ioutil.WriteFile -> os.WriteFile
  • ioutil.ReadDir -> os.ReadDir (返回 []os.DirEntry,比舊的 []fs.FileInfo 更高效)
  • ioutil.NopCloser -> io.NopCloser
  • ioutil.ReadAll -> io.ReadAll
  • ioutil.Discard -> io.Discard
  • ioutil.TempFile -> os.CreateTemp
  • ioutil.TempDir -> os.MkdirTemp

總結(jié)思路:

Go 1.16 通過(guò)引入 io/fs 接口,推動(dòng)了文件系統(tǒng)操作的標(biāo)準(zhǔn)化和解耦 。這使得代碼可以更靈活地處理不同來(lái)源的文件數(shù)據(jù),無(wú)論是來(lái)自操作系統(tǒng)、內(nèi)存、嵌入資源還是壓縮包。同時(shí),棄用 io/ioutil 并將其功能整合到 io 和 os 包中,是對(duì)標(biāo)準(zhǔn)庫(kù)進(jìn)行的一次 整理和規(guī)范化 ,使得包的功能劃分更加清晰合理。開(kāi)發(fā)者應(yīng)當(dāng)積極采用 fs.FS 接口來(lái)設(shè)計(jì)可重用、可測(cè)試的文件處理邏輯,并使用 os 和 io 包中新的或遷移過(guò)來(lái)的函數(shù)替代 io/ioutil 的功能。

責(zé)任編輯:姜華 來(lái)源: Piper蛋窩
相關(guān)推薦

2025-04-25 08:01:12

Go應(yīng)用程序部署

2025-04-21 00:05:00

2025-04-21 08:00:56

2025-04-22 08:02:23

2025-04-23 08:02:40

2025-04-21 00:00:00

Go 開(kāi)發(fā)Go 語(yǔ)言Go 1.9

2025-04-14 00:00:04

2025-04-24 09:01:46

2025-04-18 08:07:12

2025-04-14 08:06:04

2025-04-15 08:00:53

2025-04-17 08:00:48

2025-04-14 00:00:00

2025-04-11 08:02:38

2025-04-10 08:03:18

Go 1rune? 類型類型推斷

2010-07-12 10:48:21

SQL Server數(shù)

2023-08-14 08:34:14

GolangHttp

2010-07-21 16:28:33

職場(chǎng)

2015-06-23 15:48:41

Swift 2.0iOS9

2010-08-06 10:51:16

使用IBM DB2
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)