In day 2 of the go tutorial there is this exercise:
Why may it be useful to have a private type with exported fields?
For example:
package geometry
type point struct {
X, Y int;
name string;
}
Notice that point
is lowercase and thus not exported, whereas the fields X and Y are uppercase and thus are. It seems to me, that in order to have access to one of the exported fields, you would have to be able to write something like.
p.X
But in order for that to be possible, p would have to have a declaration like such:
var p geomitry.point;
or
p := new(geomitry.point);
This however is not possible (afaik), since the type declaration for point isn't exported.
In go, fields and variables that start with an Uppercase letter are "Exported", and are visible to other packages. Fields that start with a lowercase letter are "unexported", and are only visible inside their own package.
You can have private variables and functions in Go, but the trick is that you simply don't define them in the struct.
In Golang, there are no Public and Private keywords. But you can distinguish Public and Private by using the uppercase and lowercase of the name. The Public function can be called by other packages, but the Private function can only be called by the package that defines it.
This same question is presented in this Go course as:
[...]You may even have a private type with exported fields. Exercise: when is that useful?
As presented here you can access externally an element defined as internal to a package, you just can't access it directly. In the case of the structure "point" in your example, it means you CANNOT access elements of point directly, as in
// geometry.go
package geometry
type point struct {
X, Y int
}
// main.go
package main
import (
"fmt"
"./geometry"
)
func main() {
point := geometry.point{
X: 10,
Y: 20
}
fmt.Printf("Point: %#v\n", point)
}
But you CAN use the defined point to export elements that use its exported internal elements, as in
// geometry.go
package geometry
type point struct {
X, Y int
}
//Vector ...
type Vector struct {
Start point
End point
}
// main.go
package main
import (
"fmt"
"./geometry"
)
func main() {
vector := geometry.Vector{}
vector.Start.X = 10
vector.Start.Y = 10
vector.End.X = 10
vector.End.Y = 10
fmt.Printf("Vector: %#v\n", vector)
}
Result -> Vector: geometry.Vector{Start:geometry.point{X:10, Y:10}, End:geometry.point{X:10, Y:10}}
So, in my view, this mechanism is meant to give you flexibility in declaring internal data structures.
An abstract base type ?
package geometry
type point struct {
X, Y int;
}
type Point struct {
point;
name string;
}
type Rect struct {
P1, P2 point;
name string;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With