Implement struct no copy in GoLang

English 简体中文 繁体中文 ภาษาไทย Tiếng Việt
Summary

GoLang lacks an intuitive mechanism to prevent struct copying, which can be problematic for types like global configurations that should maintain a single instance. A common pattern to address this involves embedding a special noCopy struct within any type not intended for copying. This noCopy struct, which implements the sync.Locker interface with no-op Lock() and Unlock() methods, enables the go vet tool to identify instances where the containing struct is copied by value. While go vet will report warnings for such copies, the code will still compile and run successfully, making this approach a valuable development-time check rather than a compile-time enforcement.

存在某些情況,GoLang 中某些不應複製的結構體。例如,有時全域組態應該只有一個版本在整個應用程式中傳遞,而不應被複製和修改。

在 GoLang 中,沒有直觀的解決方案來防止結構體的複製。但仍然有一些方法可以利用來幫助防止在開發程式碼時發生這種情況。技巧是定義一些實現sync.Locker介面的結構體,並將此結構體嵌入任何不應複製的結構體中

// noCopy 可嵌入到不應在第一次使用後複製的結構體中。
//
// 詳細資訊請參閱 https://golang.org/issues/8005#issuecomment-190753527
// 。
type noCopy struct{}

// Lock 是 `go vet` 的 -copylocks 檢查器使用的無操作函式。
func (*noCopy) Lock() {}
func (*noCopy) UnLock() {}

下面是一個解釋上述內容的程式碼片段。

package main

import (
	"fmt"
)

type noCopy struct{}

func (*noCopy) Lock()   {}
func (*noCopy) Unlock() {}

type Demo struct {
	noCopy noCopy
}

func Copy(d Demo) {
}

func main() {
	d := Demo{}
	fmt.Printf("%+v", d)

	Copy(d)

	fmt.Printf("%+v", d)
}

現在,如果您在 main.go 檔案上執行go vet,您將看到一些錯誤,告訴您某些地方複製了結構體 (Copy())。

> go vet main.go
# command-line-arguments
.\main.go:16: Copy 傳遞鎖定值:main.Demo 包含 main.noCopy
.\main.go:21: fmt.Printf 的呼叫複製鎖定值:main.Demo 包含 main.noCopy
.\main.go:23: Copy 的呼叫複製鎖定值:main.Demo 包含 main.noCopy
.\main.go:25: fmt.Printf 的呼叫複製鎖定值:main.Demo 包含 main.noCopy

需要注意的是,上述方法不會讓編譯器編譯失敗。如果您繼續編譯和執行它,它仍然可以工作。這只為go vet 提供了另一個提示,我們通常在構建專案之前執行它,以檢查我們的原始碼中可能存在潛在問題。

> go run main.go
{noCopy:{}}{noCopy:{}}

參考:

GO VET NOCOPY NO COPY

  RELATED

  COMMENTS

0

No comment for this article.