Normally if package B
has code that directly reads/modifies A.Type
then that code should be in package A
.
At least the parts of it if that need direct access should.
To split something between separate packages A
and B
you'd normal try to isolate an API for access to A.Type
that can be expressed as an interface. Then B
would define and use this interface and A.Type
would implement it (implicitly, without needing to include B's definition of it).
Then something (possibly A
, possibily a separate package) would use B
by passing an A.Type
or *A.Type
value as appropriate.
Or depending on your design the relationship could be reversed, with B.OtherType
implicitly implementing an interface defined and used by A
.
Or both A
and B
could use each other only through interfaces; it all depends on the details.
E.g. perhaps something like:
package Game // "A"
type State struct {
data int // etc
}
func (s State) IsValid() bool { return true }
func (s *State) ChangeY(arg int) error { return nil }
// …etc…
and:
package Modifier // "B"
type GameState interface {
IsValid() bool
ChangeY(int) error
}
type M struct {
s GameState
//…
}
func New(s GameState) *M {
return &M{s: s}
}
func (m M) DoSomething() {
if s.IsValid() {
// …
}
s.ChangeY(42)
// …etc…
}