首页 > 后端开发 > Golang > 如何跨包访问Go中的私有字段?

如何跨包访问Go中的私有字段?

Linda Hamilton
发布: 2024-12-24 18:37:14
原创
616 人浏览过

How Can I Access Private Fields in Go Across Different Packages?

跨包的私有字段可访问性

考虑这样一种情况:一个包(例如 foo)中定义的结构体包含私有字段和另一个包(例如,酒吧)需要访问它们。不幸的是,Go 的包级封装禁止从外部包直接访问私有字段。

但是,访问这些私有字段的方法有限,尽管有一些注意事项:

使用反射 (Go

在 Go 1.7 之前,它是可以使用反射读取私有字段:

package bar

import "../foo"
import "fmt"
import "reflect"

func read_foo(f *foo.Foo) {
    v := reflect.ValueOf(*f)
    y := v.FieldByName("y")
    fmt.Println(y.Interface())
}
登录后复制

这种方法允许检索私有字段值,但不允许对其进行修改。

操作内存(Go >= 1.7)

在 Go 1.7 及更高版本中,一种不太理想的方法是使用不安全指针直接操作内存。通过根据字段大小和偏移量推进内存指针,可以访问私有字段:

package bar

import "../foo"
import "unsafe"

func change_foo(f *foo.Foo) {
    ptrTof := unsafe.Pointer(f)
    ptrTof = unsafe.Pointer(uintptr(ptrTof) + uintptr(8)) // Advance by the size of int
    ptrToy := (**foo.Foo)(ptrTof)
    *ptrToy = nil
}
登录后复制

由于其不可移植性和数据损坏的可能性,强烈建议不要使用此方法。

替代方案

除了直接访问私有字段之外,还有更合适的options:

  • 将需要字段访问的逻辑移至与结构相同的包中。
  • 导出提供对私有字段的受控访问的安全接口或方法。
  • 考虑使用白盒测试(通过将测试命名为 _test.go)来允许访问同一测试中的私有字段package.

请记住,封装的目的是维护数据完整性并防止意外修改。如果需要访问私有字段,请仔细考虑是否有更合适的替代方案。

以上是如何跨包访问Go中的私有字段?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板