Home >Backend Development >Golang >How Can I Access Private Fields in Go for Testing and Other Legitimate Purposes?
Accessing Private Fields in Go: Solutions for Friend Packages and White-Box Testing
In Go, struct fields are typically private by default, protecting them from access by external packages. However, there may be scenarios where you need to access private fields from another package for white-box testing or other legitimate reasons.
Method 1: Using Reflection (Go Versions Prior to 1.7)
Prior to Go 1.7, the reflect package provided a way to access and modify unexported fields using reflection. The following code demonstrates how to modify private fields using reflect:
func read_foo(f *Foo) { v := reflect.ValueOf(*f) y := v.FieldByName("y") fmt.Println(y.Interface()) }
However, modifying unexported fields using reflection will trigger a panic in Go versions 1.7 and later.
Method 2: Pointer Manipulation (Go Versions 1.7 and Later)
In Go 1.7 and later, the reflect package was updated to disallow modifying unexported fields from other packages. However, there is a risky approach that involves pointer manipulation using the unsafe package:
func change_foo(f *Foo) { ptrTof := unsafe.Pointer(f) ptrTof = unsafe.Pointer(uintptr(ptrTof) + uintptr(8)) ptrToy := (**Foo)(ptrTof) *ptrToy = nil }
Caution: Using unsafe for this purpose is strongly discouraged. It is non-portable, can break with changes to data structures, and may interfere with garbage collection.
White-Box Testing
For white-box testing, where you need access to private fields within a package, you can use the _test.go naming convention. Any files with _test.go at the end will be compiled only when running tests. This allows you to access private fields for white-box testing while keeping them private for production code.
// mypackage/foo_test.go package mypackage import ( "testing" ) func TestFoo(t *testing.T) { f := new(Foo) // Access and modify private fields within Foo }
Conclusion
Accessing private fields from another package should be done cautiously and for legitimate reasons only. While methods like reflection or unsafe pointer manipulation may provide workarounds, they come with significant risks and drawbacks. For white-box testing, the _test.go naming convention provides a safer and more convenient approach to accessing private fields within a package.
The above is the detailed content of How Can I Access Private Fields in Go for Testing and Other Legitimate Purposes?. For more information, please follow other related articles on the PHP Chinese website!