มีบางกรณีที่โครงสร้างบางตัวใน GoLang ไม่ได้ถูกสร้างมาเพื่อการคัดลอก ตัวอย่างเช่น บางครั้งการกำหนดค่าทั่วโลกซึ่งควรมีเพียงเวอร์ชันเดียวที่ส่งผ่านไปทั่วทั้งแอปพลิเคชันและไม่ควรคัดลอกและแก้ไข
ใน GoLang ไม่มีวิธีแก้ปัญหาที่เข้าใจง่ายในการป้องกันการคัดลอกโครงสร้าง แต่ก็ยังมีวิธีการบางอย่างที่สามารถใช้เพื่อช่วยป้องกันสิ่งนี้ในขณะที่พัฒนาโค้ด กลอุบายคือการกำหนดโครงสร้างบางอย่างที่ใช้ interface sync.Locker
และมีโครงสร้างนี้ฝังอยู่ในโครงสร้างใดๆ ที่ไม่ต้องการให้คัดลอก
// noCopy อาจถูกฝังอยู่ในโครงสร้างที่ไม่ควรคัดลอก
// หลังจากการใช้งานครั้งแรก
//
// ดู https://golang.org/issues/8005#issuecomment-190753527
// สำหรับรายละเอียด
type noCopy struct{}
// Lock เป็น no-op ที่ใช้โดยตัวตรวจสอบ -copylocks จาก `go vet`
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)
}
ตอนนี้ถ้าคุณรัน go vet
บนไฟล์ main.go คุณจะเห็นข้อผิดพลาดบางอย่างบอกคุณว่าคุณมีการคัดลอกโครงสร้างบางแห่ง (Copy()
)
> go vet main.go
# command-line-arguments
.\main.go:16: Copy ส่งผ่าน lock โดยค่า: main.Demo ประกอบด้วย main.noCopy
.\main.go:21: การเรียกใช้ fmt.Printf คัดลอกค่า lock: main.Demo ประกอบด้วย main.noCopy
.\main.go:23: การเรียกใช้ Copy คัดลอกค่า lock: main.Demo ประกอบด้วย main.noCopy
.\main.go:25: การเรียกใช้ fmt.Printf คัดลอกค่า lock: main.Demo ประกอบด้วย main.noCopy
สิ่งหนึ่งที่ควรทราบที่นี่คือวิธีการข้างต้นจะไม่บอกให้คอมไพเลอร์ล้มเหลวในการคอมไพล์ ถ้าคุณดำเนินการคอมไพล์และรันต่อไป มันก็ยังคงทำงานได้ สิ่งนี้เพียงแค่ให้คำแนะนำเพิ่มเติมแก่ go vet
ซึ่งโดยปกติแล้วเราจะรันก่อนที่จะสร้างโครงการเพื่อตรวจสอบว่าอาจมีปัญหาที่อาจเกิดขึ้นในโค้ดของเรา
> go run main.go
{noCopy:{}}{noCopy:{}}
อ้างอิง: