首页 > 解决方案 > 防止修改结构数据成员的惯用方法

问题描述

一些谷歌搜索的结论是:1)Go 不支持不可变/常量数据成员。2) Go 不支持私有数据成员。相反,使用包来隔离数据是惯用的。

那么防止对结构的数据成员进行后修改的惯用方法是什么?

例如,我想声明一个线程池并确定它的大小一次。

type ThreadPool struct {
    tp_size int  
}

func (tp* ThreadPool) Init(size int) {
  tp.tp_size = size;
  // Allocate space...
}

标签: go

解决方案


您将属性设为私有,因此无法从外部包访问它。

对于相同的包访问,您不能. Golang 的哲学是:你是代码的所有者,所以你可以为所欲为。

但是,如果您想使该字段不可变,您可以再次将一种数据类型包装在一个名为ImmutableSomething并存储在不同包中的结构中。例如:

package util

type ImmutableInt struct {
    val int
}

func NewImmutableInt(val int) ImmutableInt {
    return ImmutableInt{val: val}
}

func (i ImmutableInt) Get() int {
    return i.val
}

func (i ImmutableInt) Set(val int) ImmutableInt {
    return ImmutableInt{val: val}
}

然后你可以使用它:

package app

import "util"

type ThreadPool struct {
    size util.ImmutableInt
}

func NewThreadPool(size int) ThreadPool {
    return ThreadPool{size: util.NewImmutableInt(size)}
}

func test() {
    pool := NewThreadPool(10)

    // you cannot do this because ImmutableInt is in another package
    pool.size.val = 3

    // this  won't work
    pool.size.Set(3)

    // but you can do this. which is weird. 
    // and praying when someone does this, they know something not right
    pool.size = util.NewImmutableInt(3)
}

推荐阅读