In the following code, I have a lower level module RelationshipBrowser
defined a FindAllChildrenOf
method and I have a struct Relationships
that has the property relations
which is a slice and another struct named Research
which as the property browser
. I declared a receiver function FindAllChildrenOf
for Relationships
and another receiver function Investigate
for Research
, I think my question is, when I implement the logics in the function Investigate
it's clearly calling the browser interface to trigger the function FindAllChildrenOf
and go automatically knows that I am referring to type Relationship
. My confusion is, how does RelationshipBrowser and Relationships connect in this context while they seem to have no connection?
const (
Parent Relationship = iota
Child
Sibiling
)
type Person struct {
name string
}
type Info struct{
from *Person
relatiionship Relationship
to *Person
}
// low-level module
type RelationshipBrowser interface{
FindAllChildrenOf(name string)[]*Person
}
type Relationships struct{
relations []Info
}
func (r *Relationships)AddParentAndChild(parent,child *Person){
r.relations = append(r.relations, Info{parent,Parent,child})
r.relations = append(r.relations, Info{child,Child,parent})
}
func (r *Relationships)FindAllChildrenOf(name string)[]*Person{
result:= make([]*Person,0)
for i,v:= range r.relations{
if v.relatiionship == Parent && v.from.name==name{
result = append(result, r.relations[i].to)
}
}
return result
}
// high-level module
type Research struct{
// break DIP
// relationships Relationships
browser RelationshipBrowser
}
func (r *Research)Investigate(){
// relations:= r.relationships.relations
// for _, rel := range relations{
// if rel.from.name == "John" && rel.relatiionship == Parent{
// fmt.Println("John has a child called", rel.to.name)
// }
// }
children:=r.browser.FindAllChildrenOf("John")
for _,child:=range children{
fmt.Println("John has a child called", child.name)
}
}
func main(){
parent:= Person{"John"}
child1:= Person{"Chris"}
child2:= Person{"Matt"}
relationships:= Relationships{}
relationships.AddParentAndChild(&parent,&child1)
relationships.AddParentAndChild(&parent,&child2)
r := Research{&relationships}
r.Investigate()
}
CodePudding user response:
go automatically knows that I am referring to type Relationship.
Yes, because Go knows the exact address of the RelationshipBrowser, so it can know everything if it want. You can know everything too, through the reflection, see https://go.dev/blog/laws-of-reflection
In your code, you explicitly pass the address here:
r := Research{&relationships}
RelationshipBrowser and Relationships connect together by this address, because Research think of it as a RelationshipBrowser, but it's actually a Relationships.
CodePudding user response:
I just figured out that by calling r.Investigate
, the program knows I am referring to the Relationship
struct. I am still a go beginner, so the learning curve is deep.