Wednesday 15 April 2015

Go: disallow direct struct initalization -



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