【问题标题】:Idiomatic way to prevent modification to struct data members [duplicate]防止修改结构数据成员的惯用方法[重复]
【发布时间】:2020-01-11 07:58:50
【问题描述】:

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

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

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

type ThreadPool struct {
    tp_size int  
}

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

【问题讨论】:

    标签: go


    【解决方案1】:

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

    对于相同的包访问权限,您不能。 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)
    }
    

    【讨论】:

    • ImmutableInt{size}util 包之外的编译时错误,请参阅thisthis
    • @icza 是的,你说得对。我刚刚修好了。谢谢。
    • 将 int 包装在一个结构中(然后是一个 in 包)是有意义的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 2016-03-29
    • 1970-01-01
    相关资源
    最近更新 更多