Go: disallow direct struct initalization -
given next packages in go, possible prevent direct initialization of bar
bar{..}
without de-exposing bar
package?
package bar
:
package bar import () type bar struct { string b string } func newbar(baz string) bar{ homecoming bar{a:baz, b:baz+baz} }
package main
:
package main import ( "fmt" "./bar" ) func main() { x := bar.newbar("sad") //all bars should created y := bar.bar{a: "fadss"} //and should disallowed bzzbar(x) bzzbar(y) } func bzzbar(bzz bar.bar) { //but can't 'bar -> bar' because want utilize type fmt.println(bzz) }
my gut feeling says can't done, valid answer.
the idiom used in go standard library is:
package bar
package bar import ( "fmt" ) type bar struct { string b string } func new(baz string) *bar { homecoming &bar{a: baz, b: baz + baz} } func (b *bar) bzzbar() { fmt.println(*b) }
package main
package main import ( "bar" ) func main() { x := bar.new("sad") //all bars should created x.bzzbar() // error: unknown bar.bar field 'a' in struct literal // y := bar.bar{a: "fadss"} //and should disallowed }
output:
{sad sadsad}
addendum:
the go programming language specification
the 0 value
when memory allocated store value, either through declaration or phone call of create or new, , no explicit initialization provided, memory given default initialization. each element of such value set 0 value type: false booleans, 0 integers, 0.0 floats, "" strings, , nil pointers, functions, interfaces, slices, channels, , maps. initialization done recursively, instance each element of array of structs have fields zeroed if no value specified.
another idiom used in go standard library create 0 values meaningful. example, if new
has not been explicitly initialized have 0 value default of false
.
type bar struct { new bool string b string }
for example,
package bar import ( "fmt" ) type bar struct { new bool string b string } func new(baz string) *bar { homecoming &bar{new: true, a: baz, b: baz + baz} } func (b *bar) notnew() { if b == nil || !b.new { panic("bar.bar not bar.new") } } func (b *bar) bzz() { b.notnew() fmt.println(*b) }
.
package main import ( "bar" ) func main() { x := bar.new("sad") //all bars should created x.bzz() // error: unknown bar.bar field 'a' in struct literal // y := bar.bar{a: "fadss"} //and should disallowed // var b bar.bar // panic: bar.bar not bar.new // b.bzz() // var b = bar.bar{} // panic: bar.bar not bar.new // b.bzz() // var bp *bar.bar // panic: bar.bar not bar.new // bp.bzz() // var bp = new(bar.bar) // panic: bar.bar not bar.new // bp.bzz() }
output:
{true sad sadsad}
go
No comments:
Post a Comment