在Golang中,是否可以定义不可变的结构体?一旦初始化,则仅对结构体字段进行读取操作,不能修改字段值。如果可以,如何实现。
在Golang中,是否可以定义不可变的结构体?一旦初始化,则仅对结构体字段进行读取操作,不能修改字段值。如果可以,如何实现。
通过将结构体的成员设为非导出并提供读取器,可以使其在包外部只读。例如:
package mypackage
type myReadOnly struct {
value int
}
func (s myReadOnly) Value() int {
return s.value
}
func NewMyReadonly(value int) myReadOnly{
return myReadOnly{value: value}
}
使用方法:
myReadonly := mypackage.NewMyReadonly(3)
fmt.Println(myReadonly.Value()) // Prints 3
struct
来模拟 toml
配置文件。要解析 TOML,我们需要导出字段。另一方面,我希望仅在应用程序启动时创建配置结构,因此将其设置为只读对我有意义。我似乎找不到同时解决这两个问题的解决方案。 - Abhijit无法以通用的方式标记字段/变量为只读。您能做的唯一事情是将字段/变量标记为未导出(首字母小写),并提供公共的getter来防止其他包编辑变量。
type S struct {
A string
B []string
}
func main() {
x := S{"x-A", []string{"x-B"}}
y := x // copy the struct
y.A = "y-A"
y.B[0] = "y-B"
fmt.Println(x, y)
// Outputs "{x-A [y-B]} {y-A [y-B]}" -- x was modified!
}
注意:因此,您必须非常小心,并且不要假定通过值传递参数会使其不可变。
有一些深拷贝库尝试通过(慢速)反射来解决这个问题,但它们效果不佳,因为私有字段无法使用反射访问。因此,为了避免竞态条件而进行防御性复制将是困难的,需要大量样板代码。甚至没有一个克隆接口可以标准化此过程。
[3]float32
或 [10]int
,请注意明确的大小)是一个值,并且像结构体一样进行复制。实际上,[3]int
和 struct{x,y,z int}
具有相同的内存布局,与 []int
完全不同。 - kbolinotype Maybe[T any] struct {
v T
valid bool
}
func (m Maybe[T]) Just() T {
return m.v
}
func (m Maybe[T]) Nothing() bool {
return m.valid == false
}
func Just[T any](v T) Maybe[T] {
return Maybe[T]{
v: v,
valid: true,
}
}
func Nothing[T any]() Maybe[T] {
return Maybe[T]{
valid: false,
}
}
maybe 结构体是一个不可变的结构体