Go Wiki: 註釋

Go 支援 C 風格的 /* */ 塊註釋和 C++ 風格的 // 行註釋。行註釋是常用形式。

文件註釋

包和匯出的名稱應該有文件註釋。文件註釋遵循某些約定並支援簡單的格式化語法。有關更多資訊,請參閱 Go 文件註釋

指令

某些工具,包括 go 工具編譯器 支援可能出現在註釋中的指令。除了少數為相容性而存在的例外情況,這些註釋指令都是以 //go: 開頭的行註釋,且 //go: 之間沒有空格。

go 工具指令

//go:build

go 工具 支援 構建約束。這些是 //go:build 指令,描述了檔案應包含在包中的條件。

約束的示例用法有

  • //go:build ignore 是一種約定,可以阻止檔案成為構建的一部分。這通常用於生成原始碼的程式。
  • //go:build linux 只會在為 Linux 構建時構建檔案。這通常可用於任何作業系統或架構。
  • //go:build cgo 只會在支援 cgo 時構建檔案。
  • //go:build purego 是一種約定,只會在使用純 Go 時構建檔案;也就是說,不使用 cgo 或彙編程式碼。

約束也可以是表示式

  • //go:build amd64 || arm64 將在 amd64 或 arm64 上構建檔案。

約束可以設定編譯檔案時使用的語言版本。例如,約束 //go:build go1.23 將只在使用 Go 1.23 或更高版本時構建檔案,並在構建檔案時使用 Go 1.23 語言語義。如果 go.mod 是早期版本,這會很方便。例如,這可以允許定義提供 Go 1.23 函式迭代器 的函式,但僅當使用 Go 1.23 或更高版本構建時。

在 Go 1.16 及更早版本中,構建約束使用以 // +build 開頭的註釋編寫,並且不允許通用表示式。gofmt 程式 會將舊的 // +build 語法重寫為新的 //go:build 語法。

//go:generate

go generate 命令查詢 //go:generate 指令以查詢要執行的命令。

此指令的一個示例是 //go:generate stringer -type=Enum,用於執行 stringer 工具,為整數型別的值定義 String 方法。

//go:embed

embed 包 使用 //go:embed 指令將原始檔嵌入到生成的二進位制檔案中。單個檔案可以嵌入為 string[]byte。一組檔案可以嵌入為 embed.FS,它實現了 fs.FS 介面

例如,名為 templates 的子目錄的內容可以使用如下指令嵌入到程式中:

//go:embed templates
var templatesSource embed.FS

// tmpls holds the parsed embedded templates.
// This does not read files at run time,
// it parses the data embedded in the binary.
var tmpls = template.ParseFS(templatesSource)

編譯器指令

Go 編譯器支援 幾個指令

//line

//line 指令允許設定用於以下程式碼的檔名、行號和列號。出於歷史原因,此指令不以 //go: 開頭。當 Go 檔案由其他源生成時,這很有用,並且錯誤訊息或堆疊回溯引用該其他原始檔而不是生成的原始檔時也很有用。

在一行內,可以使用 /*line 塊註釋,這有助於設定列位置。

//line foo.src:10
var x = /*line foo.src:20:5*/ 3

//go:noescape

//go:noescape 指令後面必須是一個沒有函式體的函式宣告,表示一個未用 Go 實現的函式。該指令告訴編譯器,傳遞給函式的指標不會逸出到堆,也不會由函式返回。

其他編譯器指令

還有許多其他具有特殊用途的編譯器指令。有關詳細資訊,請參閱 編譯器文件

  • //go:linkname
  • //go:noinline
  • //go:norace
  • //go:nosplit
  • //go:uintptrescapes
  • //go:wasmimport

未文件化的編譯器指令

編譯器還支援一些未文件化的指令。通常,這些不應在使用者程式碼中使用。其中一些僅在編譯執行時包時可用。

  • //go:nocheckptr
  • //go:nointerface
  • //go:nowritebarrier
  • //go:nowritebarrierrec
  • //go:registerparams
  • //go:systemstack
  • //go:uintptrkeepalive
  • //go:yeswritebarrierrec

cgo 註釋

cgo 工具 使用在 import "C" 語句之前立即出現的一個或多個註釋序列。這個註釋序列,稱為 cgo 序言,定義了 Go 程式碼可以使用特殊 C 包引用的名稱。

package main

// #include <stdio.h>
import "C"

func main() {
    C.puts(C.CString("hello world"))
}

在序言中,cgo 識別以 #cgo 開頭的指令。這些指令可用於設定要使用的 C 編譯器和連結器標誌,或描述某些 C 函式的行為。有關完整詳細資訊,請參閱 cgo 文件

cgo 匯出

在使用 cgo 的檔案中,可以使用 //export 指令使 Go 函式對 C 程式碼可見。語法是在 Go 函式 GoName 之前的註釋中寫 //export CName。這將安排 C 呼叫函式 CName 實際上會呼叫 Go 函式 GoName。有關更多詳細資訊,請參閱 cgo 文件

cgo 編譯器指令

cgo 工具生成 Go 程式碼,並且生成的程式碼使用一些特殊指令,這些指令主要僅在 cgo 生成的程式碼中可用。除了 cgo 原始碼中,這些指令大部分未文件化。

  • //go:cgo_dynamic_linker
  • //go:cgo_export_dynamic
  • //go:cgo_export_static
  • //go:cgo_import_dynamic
  • //go:cgo_import_static
  • //go:cgo_ldflag
  • //go:cgo_unsafe_args

此內容是 Go Wiki 的一部分。