type (
A struct {
a string
}
B struct {
b *A.a
}
)
I get this error:
A.a undefined (type A has no method a)
Am I missing something here? Or is it not allowed in Go?
When you define a struct field, you have to specify its name and its type like you did with struct A.a
. But in struct B
:
b *A.a
*A.a
is not a type.
You can't embed a field of a struct
in another struct. Note that however you can embed complete structs in another by omitting the name part like this:
type (
A struct {
a string
}
B struct {
A
}
)
The result is that all the fields and methods of type A
will also be member of struct B
. If you need the embedded struct A
of B
, you can access it by referring to it as the type name:
var b B
fmt.Println(b.A)
Another thing you can do is have a field in B
which is a pointer and it points to the field of an existing value of type A
:
B struct {
ap *string
}
a := A{a:"test"}
b := B{ap:&a.a} // B.ap will point to a.a
fmt.Println(*b.ap) // Prints "test"
The problem is that you're using *A.a
as the type specifier for field b
. The only thing you're missing is that you should have b string
or b *string
there (if you want a string field in struct B at least).
Now if your goal is to do something more like 'inheriting' the field then you should embed A
in B
which will give B
a property called a
. That would look like this;
type B struct {
A
}
This is the most similar construct to inheritance Go offers. If you were to embed here you would be able to do something like;
var instanceOfB = &B{}
fmt.Println(instanceOfB.a)
Which is functionally equivalent of having B inherit from A (in this case, the two things are not the same though and behavior is different in many. I just think it's helpful to compare/contrast to inheritance). At this point you can access an property or method on A
directly from an instance of B
. It's best to avoid name collisions though they won't cause a compiler error. If you do have naming collisions between embedded types or the embeddor and an embedded type the decision of which method/property to use is made at runtime and I'm not sure what the resolution rules are but I think you can find them in the language spec.
Now my last idea... If your goal is to reference the a
property in an instance of A
from some instance of B
, you just want to include a sting pointer in B
and set it to &A.a
in your constructor a static initializer when you instantiate B
. However this is probably a bad practice as it defies the concept of encapsulation and is just very obviously error prone.