Edit: I'm not asking how to initialize variables correctly. I'm asking how to prevent them from being initialized incorrectly, so that functions that take that type don't have to explicitly validate their arguments.
In Go, I have a type that contains maps, e.g.:
package foo
type Bar struct {
baz map[string]int
total int
}
func NewBar() *Bar {
return &Bar{baz: map[string]int{}}
}
func (b *Bar) IncrementBaz(key string) {
f.baz[key] = f.baz[key] + 1
f.total++
}
// ...
If another package initializes the type and then tries to write to it, it will try to write to a nil map, causing a segfault:
package main
import "foo"
func main() {
var b foo.Bar
b.IncrementBaz("some_key") // write to nil map -> segfault
// ...
}
To prevent this, I want to make it so that other packages can't initialize an empty foo.Bar
.
I can't simply make it unexported, because I want functions in other packages to be able to declare it as an argument or return type. If I wrap it in an interface, I get a similar problem:
package "foo"
type Bar interface {
IncrementBaz(string)
// ...
}
type bar struct {
baz map[string]int
total int
}
func NewBar() Bar {
return &bar{baz: map[string]int{}}
}
func (b *bar) IncrementBaz(key string) {
f.baz[key] = f.baz[key] + 1
f.total++
}
// ...
Similar problem:
package main
import "foo"
func main() {
var b foo.Bar
b.IncrementBaz("some_key") // method call on nil interface -> segfault
// ...
}
Is there any way to have an exported type that only the package that declares it can initialize it?