1

Conclusions from a few Google search are: 1) Go doesn't support immutable / const data members. 2) Go doesn't support private data members. Instead, it's idiomatic to use package to isolate data.

So what's the idiomatic way to prevent post-modification to a data member of a struct?

For example, I'd like to declare a thread pool and decide its size once.

type ThreadPool struct {
    tp_size int  
}

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

1 Answers1

2

You make the attribute privately so it cannot be accessed from the outside package.

For the same package access, you can't. The philosophy of Golang is: you are the owner of the code, so you can do anything you want.

However, if you want to make the field immutable, you can wrap again one data type in a struct named ImmutableSomething and stored in the different packages. For example:

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}
}

Then you can use that:

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)
}
hqt
  • 29,632
  • 51
  • 171
  • 250
  • `ImmutableInt{size}` is a compile-time error outside of the `util` package, see [this](https://stackoverflow.com/questions/45213365/golang-struct-literal-syntax-with-unexported-fields/45213441#45213441) and [this](https://stackoverflow.com/questions/38369350/how-to-clone-a-structure-with-unexported-field/38370382#38370382). – icza Jan 11 '20 at 11:48
  • @icza yes, you right. I just fixed it. Thanks. – hqt Jan 11 '20 at 12:54
  • Wrapping int in a struct (and then a in package) makes sense. Thanks! – minglotus Jan 11 '20 at 18:01
  • "The philosophy of Golang is: you are the owner of the code, so you can do anything you want.", But I can't make my struct immutable :D :D – man of knowledge Sep 16 '22 at 02:19