unable to save pointer dereference in pointer receiver struct golang OOP - oop

package main
import "fmt"
type rabbit struct {
food string
}
func (r *rabbit) change_food() {
(*r).food = "salad"
}
func main() {
var roger rabbit = rabbit{food: "carrot"}
(&roger).change_food()
fmt.Println(roger) //output --> salad
}
code above works, but I'd like to save (in the pointer receiver) the pointer dereference in a variable instead of writing every time (*r) without using shorthand because in my opinion with pointer receivers they are unclear/confusing. I prefer explicit dereference for cleaner code https://tour.golang.org/moretypes/4.
I tried this code:
package main
import "fmt"
type rabbit struct {
food string
}
func (r *rabbit) change_food() {
deref := *r //deref := (*r); var deref rabbit = (*r) also don't work
deref.food = "salad"
}
func main() {
var roger rabbit = rabbit{food: "carrot"}
(&roger).change_food()
fmt.Println(roger) //output --> carrot. I wanted salad
}
to mkopriva:
I'd like to not use (*r) form, like for example I did with memory address now:
package main
import "fmt"
type rabbit struct {
food string
}
func (r *rabbit) change_food() {
(*r).food = "salad"
}
func main() {
var roger rabbit = rabbit{food: "carrot"}
var p *rabbit = &roger
p.change_food() //before It was (&roger).change_food(), now code is cleaner
fmt.Println(roger) //output --> salad
}

Go automatically converts to and from pointers, both when calling methods, and when accessing attributes:
package main
import "fmt"
type rabbit struct {
food string
}
func (r *rabbit) change_food() {
r.food = "salad"
}
func main() {
var roger = rabbit{food: "carrot"}
roger.change_food()
fmt.Println(roger)
}
change_food receiver takes a pointer, so even though roger is not a pointer, Go handles that automatically.
Similarly, even though food is an attribute of a rabbit, not a *rabbit, Go figures this out hand handles things properly.
You can't dereference a pointer and then change the data at the address of that pointer. That's why pointers exist - so you can change the underlying data instead of passing a copy.
If it's just a question of a naming convention, you could always define the receiver's variable name with a p:
func (rp *rabbit) change_food() {
...
But it's not common in Go languages to denote pointer types like this, perhaps because Go is a lot smarter at typing than something like C, and it doesn't really get confusing between pointers and values.

Related

How to define external functions that return type unions in Kotlin/JS?

I'm writing external declarations for LeafletJS 1.8.0, a JavaScript library, using Kotlin 1.6.21.
The Polyline class has a function, getLatLngs() that can return any of these types:
Array<LatLng>
Array<Array<LatLng>>
Array<Array<Array<LatLng>>>
Of course the setter is easy to overload to handle a type-union
open external class Polyline {
open fun setLatLngs(latlngs: Array<LatLng>): Polyline<T>
open fun setLatLngs(latlngs: Array<Array<LatLng>>): Polyline<T>
open fun setLatLngs(latlngs: Array<Array<Array<LatLng>>>): Polyline<T>
}
However it's not possible to overload the getter
open external class Polyline {
// ERROR: Conflicting overloads
open fun getLatLngs(): Array<LatLng>
open fun getLatLngs(): Array<Array<LatLng>>
open fun getLatLngs(): Array<Array<Array<LatLng>>>
}
As a compromise I can set the return type to dynamic and add a comment so users can see the intention.
open external class Polyline {
open fun getLatLngs(): dynamic /* Array<LatLng> | Array<Array<LatLng>> | Array<Array<Array<LatLng>>> */
}
There's an open ticket KT-13108, and an update in November 2021 indicates direct Kotlin support for type unions won't be available until after Kotlin 1.7 is released.
Is there a better way of implementing the external function so the return type is type safe, or users can see the available types that might be returned, and handle each appropriately? What's the idiomatic practice?
Problem:
You are looking for an idiomatic way to describe union types for external declarations with:
Type safety (to ensure protect against runtime exceptions)
Output Type Annotations (for documentation purposes and also IDE code completion)
Control flow that handles each type in the union (so the union type can be used in Kotlin)
Long story short, for any general representation of a JS union-type in Kotlin, it's not possible to hit all three of these criteria without having more information about the instances of those types (due to type-erasure which I'll explain). But, In your case and the vast majority of cases, there is a nice trick to do this by using Kotlin's extension functions.
Solution:
There are two cases that I'll explain what to do to hit these criteria as best as possible:
Union of types that don't use generics (like Cat | Dog | string)
Union of types that do use generics (This is your case as Array<LatLng>, Array<Array<LatLng>>, and Array<Array<Array<LatLng>>> each use Generics for their types)
Union types that don't use Generics:
Say you had the Kotlin external declaration for AnimalOwner that is currently using dynamic as an output for its getPet method:
AnimalOwner.kt (draft)
/*
pretend right here that the package is declared
and file:JsModule decorators are present
*/
external class Cat
external class Dog
external class AnimalOwner {
fun setPet(pet: Cat) // sets the owner's pet to a Cat
fun setPet(pet: Dog) // sets the owner's pet to a Dog
fun setPet(pet: String) // sets the owner's pet to a String
fun getPet(): dynamic // Union of types (Cat, Dog, String)
}
One can specify an external interface to represent the output type. Then, using extension functions, one can define how to cast/morph each instance into each type (or return null if it can't):
Pet.kt
/*
pretend right here that the package is declared
However, JsModule decorators are NOT (and cannot be) present here
*/
// created an interface and gave it an arbitrary name that fits
// what the output to getPet would represent
sealed external interface Pet // we sealed Pet to disallow others from inheriting it
// Create extension functions with fitting names which cast/morph to each type
// (these are not defined externally, they are defined in Kotlin itself):
inline fun Pet.asCat(): Cat? = this as? Cat
inline fun Pet.asDog(): Dog? = this as? Dog
inline fun Pet.asString(): String? = this as? String
Now, we can replace the dynamic keyword in AnimalOwner with Pet (the interface just created):
AnimalOwner.kt (revised)
/*
pretend right here that the package is declared
and JsModule decorators are present
*/
external class Cat
external class Dog
external class AnimalOwner {
fun setPet(pet: Cat)
fun setPet(pet: Dog)
fun setPet(pet: String)
fun getPet(): Pet // <- changed from dynamic to Pet
}
We can now use AnimalOwner by calling each extension function and checking if it is null or not:
fun printPetOf(animalOwner: AnimalOwner) {
val pet = animalOwner.getPet()
pet.asCat()?.also { cat -> console.log("I have a Cat") }
pet.asDog()?.also { dog -> console.log("I have a Dog") }
pet.asString()?.also { animalStr -> console.log("I have a $animalStr") }
}
fun test() {
val johnSmith = AnimalOwner()
johnSmith.setPet(Cat()) // johnSmith has a cat
printPetOf(johnSmith) // console: "I have a Cat"
johnSmith.setPet(Dog()) // johnSmith now has a dog
printPetOf(johnSmith) // console: "I have a Dog"
johnSmith.setPet("Mouse") // johnSmith now has a Mouse
printPetOf(johnSmith) // console: "I have a Mouse"
}
Union types that do use Generics:
This case is a little more complicated due to type-erasure. Let's use a similar example to AnimalOwner where now the owner is specifying lists of Dogs, Cats, or a String of animals:
AnimalOwner.kt (draft)
/*
pretend right here that the package is declared
and JsModule decorators are present
*/
external class Cat
external class Dog
external class AnimalOwner {
fun setPets(pets: List<Cat>) // sets the owner's pets to be a list of Cats
fun setPets(pets: List<Dog>) // sets the owner's pets to be a list of Dogs
fun setPets(pets: String) // sets the owner's pets to a String
fun getPets(): dynamic // Union of types (List<Cat>, List<Dog>, String)
}
At this point, if we attempt to do the same procedure to create an output type as before, we run into a problem when creating casting/morphing functions:
Pets.kt (ERROR)
/*
pretend right here that the package is declared
However, JsModule decorators are NOT (and cannot be) present here
*/
sealed external interface Pets // we sealed Pets to disallow others from inheriting it
inline fun Pets.asCats(): List<Cat>? = this as? List<Cat> // Possible Bug
inline fun Pets.asDogs(): List<Dog>? = this as? List<Dog> // Possible Bug
inline fun Pets.asString(): String? = this as? String
Specifically, we must change the following code this as? List<Cat> and this as? List<Dog> because Generics Types like List<T> lose information on the generic parameter T at runtime. This loss of information is called type-erasure (for more information see here). We must replace this with this as? List<*> for both extension methods because we can't know generics at runtime. This now creates another problem, as of now we cannot delineate between a list of Dogs and a list of Cats. This is where we require some outside knowledge of instances of these lists and how JavaScript getPets() method treats them. This is project specific so for the sake of this example I am going to pretend I have done some research to determine this outside knowledge we speak of.
So let's say we found out that our corresponding JavaScript method for getPets() always represents the returning of an empty list as list of Cats.
Now we have enough information to correct our code to delineate List<Cats> and List<Dog> even though we only have access to List<*>:
Pets.kt (revised)
/*
pretend right here that the package is declared
However, JsModule decorators are NOT (and cannot be) present here
*/
sealed external interface Pets
inline fun Pets.asCats(): List<Cat>? {
val listOfSomething = this as? List<*>
return listOfSomething?.let {
if (it.isEmpty() || it[0] is Cat) {
#Suppress("UNCHECKED_CAST")
it as List<Cat>
} else {
null
}
}
}
inline fun Pets.asDogs(): List<Dog>? {
val listOfSomething = this as? List<*>
return listOfSomething?.let {
if (it.isNotEmpty() && it[0] is Dog) {
#Suppress("UNCHECKED_CAST")
it as List<Dog>
} else {
null
}
}
}
inline fun Pets.asString(): String? = this as? String
Now, in AnimalOwner, we can change the output type of getPets from dynamic to Pets:
AnimalOwner.kt (revised)
/*
pretend right here that the package is declared
and JsModule decorators are present
*/
external class Cat
external class Dog
external class AnimalOwner {
fun setPets(pets: List<Cat>)
fun setPets(pets: List<Dog>)
fun setPets(pets: String)
fun getPets(): Pets // <- changed from dynamic to Pets
}
We can then use AnimalOwner the same way as the non-Generic case:
fun printPetOf(animalOwner: AnimalOwner) {
val pets = animalOwner.getPets()
pets.asCats()?.also { cats -> console.log("I have Cats") }
pets.asDogs()?.also { dogs -> console.log("I have Dogs") }
pets.asString()?.also { animalsStr -> console.log("I have $animalsStr") }
}
fun test() {
val johnSmith = AnimalOwner()
johnSmith.setPets(listOf(Cat(), Cat())) // johnSmith has two cats
printPetOf(johnSmith) // console: "I have Cats"
johnSmith.setPets(listOf<Cat>()) // johnSmith has an empty room of cats (I wonder where they went)
printPetOf(johnSmith) // console: "I have Cats"
johnSmith.setPets(listOf<Dog>()) // johnSmith STILL has 0 cats (Schrodinger's cats?)
printPetOf(johnSmith) // console: "I have Cats"
johnSmith.setPets(listOf(Dog(), Dog(), Dog())) // johnSmith has 3 dogs
printPetOf(johnSmith) // console: "I have Dogs"
johnSmith.setPets("a Mouse, a Horse, and a Sheep") // johnSmith now has "a Mouse, a Horse, and a Sheep"
printPetOf(johnSmith) // console: "I have a Mouse, a Horse, and a Sheep"
}
I would approach this problem like this.
Step 1: Create an abstract external return type say LatLngResult
external interface LatLngResult
Step 2: Set this return type as the return type to your methods returning unions
open external class Polyline {
open fun getLatLngs(): LatLngResult
}
Step 3: Add extension functions to cast your return type as desired
inline fun LatLngResult.asArray1() = asDynamic<Array<LatLng>>()
inline fun LatLngResult.asArray2() = asDynamic<Array<Array<LatLng>>>()
inline fun LatLngResult.asArray3() = asDynamic<Array<Array<Array<LatLng>>>>()
Step 4: Use the function
val res: LatLngResult = polyline.getLatLngs()
// case 1
val array1 : Array<LatLng> = res.asArray1()
// case 2
val array2 : Array<Array<LatLng>> = res.asArray2()
// case 3
val array3 : Array<Array<Array<LatLng>>> = res.asArray3()
Note 1: Just like you would approache it in typescript, you still need to know when is it convinient to use array1, array2, array3
Note 2: Specifying types is still optional in kotlin, I just added them here to make this answer easily digestable

Non-interface methods in interface implementation

I have an interface which defines a method. I have a struct which implements this interface. In it, I have implemented the methods from this interface and also have additional methods defined.
For example:
package main
import (
"fmt"
)
type Animal interface {
MakeNoise()
}
type Dog struct {
color string
}
/* Interface implementation */
func (d *Dog) MakeNoise() {
fmt.Println("Bark!")
}
/* End Interface implementation */
func (d *Dog) WagTail() {
fmt.Println(d.color + " dog: Wag wag")
}
func NewDog(color string) Animal {
return &Dog{color}
}
func main() {
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
}
On Playground: https://play.golang.org/p/B1GgoNToNl_l
Here, WagTail() is not part of the Animal interface but belongs to the Dog struct. Running this code gives an error
dog.WagTail undefined (type Animal has no field or method WagTail).
Is there a way I could have a struct adhere to an interface and also define it's own methods?
This may help you.
d := dog.(*Dog)
d.WagTail()
On Playground: https://play.golang.org/p/KlNqpmvFTJi
The error described it all:
dog.WagTail undefined (type Animal has no field or method WagTail)
To implement an interface you should implement all methods defined inside it.
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
Now NewDog returns Animal interface which contains MakeNoise method but not WagTail.
The only way to manage your requirement is either create a variable of struct type Dog and then you can call any method having Dog as receiver.
d := &Dog{"Brown"}
d.WagTail()
Or you can return the pointer to Dog struct from NewDog method just like you did in your code mentioned in the comment as:
func NewDog(color string) *Dog {
return &Dog{color}
}
But if the method is not defined in interface you cannot implement it using the struct as method receiver.
Golang provides a way in which:
You can ask the compiler to check that the type T implements the
interface I by attempting an assignment using the zero value for T or
pointer to T, as appropriate
type T struct{}
var _ I = T{} // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.
If T (or *T, accordingly) doesn't implement I, the mistake will be caught at compile time.
If you wish the users of an interface to explicitly declare that they
implement it, you can add a method with a descriptive name to the
interface's method set. For example:
type Fooer interface {
Foo()
ImplementsFooer()
}
A type must then implement the ImplementsFooer method to be a Fooer, clearly documenting the fact and announcing it in godoc's output.
type Bar struct{}
func (b Bar) ImplementsFooer() {}
func (b Bar) Foo() {}
Most code doesn't make use of such constraints, since they limit the
utility of the interface idea. Sometimes, though, they're necessary to
resolve ambiguities among similar interfaces.
You can definitely do it, one such method is using type assertion as shown in the other answer here. Otherwise the answer by #Himanshu here describes the situation very well.
I would like to add to the discussion to further describe how you
could have a struct adhere to an interface and also define it's own methods
The MakeDog method returns an Animal, and there are a number of reasons you may consider returning a Dog (or whichever concrete type) directly.
The reason I bring this up is because of something someone told me about creating methods when I first started programming in Go:
Accept an Interface and return a Concrete type (such as a Struct)
Interfaces can accept any concrete type. That's why they are used when you don't know the type of argument you are passing to the function.
I did a google search with the following terms and quite a few articles turned up
golang accept interface, return struct
For example: https://mycodesmells.com/post/accept-interfaces-return-struct-in-go and http://idiomaticgo.com/post/best-practice/accept-interfaces-return-structs/
I have put together a little bit of a demo extending on your concepts in your question to try and clearly describe interface methods as well as methods and attributes for specific types
Taken from this snippet on Playground
package main
import (
"fmt"
)
type Animal interface {
MakeNoise() string
}
// printNoise accepts any animal and prints it's noise
func printNoise(a Animal) {
fmt.Println(a.MakeNoise())
}
type pet struct {
nLegs int
color string
}
// describe is available to all types of Pet, but not for an animal
func (p pet) describe() string {
return fmt.Sprintf(`My colour is "%s", and I have "%d" legs`, p.color, p.nLegs)
}
type Dog struct {
pet
favouriteToy string
}
// MakeNoise implements the Animal interface for type Dog
func (Dog) MakeNoise() string {
return "Bark!"
}
// WagTail is something only a Dog can do
func (d Dog) WagTail() {
fmt.Println("I am a dog,", d.pet.describe(), ": Wags Tail")
}
type Cat struct {
pet
favouriteSleepingPlace string
}
// MakeNoise implements the Animal interface for type Cat
func (Cat) MakeNoise() string {
return "Meow!"
}
// ArchBack is something only a Cat can do
func (c Cat) ArchBack() {
fmt.Println("I am a cat,", c.pet.describe(), ": Arches Back")
}
type Bird struct {
pet
favoritePerch string
}
// MakeNoise implements the Animal interface for type Cat
func (Bird) MakeNoise() string {
return "Tweet!"
}
// Hop is something only a Bird can do
func (c Bird) Hop() {
fmt.Println("I am a bird,", c.pet.describe(), ": Hops to a different perch")
}
func main() {
dog := Dog{
pet: pet{nLegs: 4, color: "Brown"},
favouriteToy: "Ball",
}
printNoise(dog)
dog.WagTail()
cat := Cat{
pet: pet{nLegs: 4, color: "Tabby"},
favouriteSleepingPlace: "Sofa",
}
printNoise(cat)
cat.ArchBack()
bird := Bird{
pet: pet{nLegs: 2, color: "Rainbow"},
favoritePerch: "Back of Cage",
}
printNoise(bird)
bird.Hop()
}
Yes, you can run methods that are not part of the interface. There were two issues in the code preventing it from running properly.
The function NewDog returns the type Animal. The WagTale method is attached to Dog not Animal which gave an error. The return type has been changed to Dog.
Pointers are not needed in this code and have been removed.
After these adjustments, the code runs and properly and all methods execute as expected.
Link on Go playground: https://play.golang.org/p/LYZJiQND7WW
package main
import (
"fmt"
)
type Animal interface {
MakeNoise()
}
type Dog struct {
color string
}
/* Interface implementation */
func (d Dog) MakeNoise() {
fmt.Println("Bark!")
}
/* End Interface implementation */
func (d Dog) WagTail() {
fmt.Println(d.color + " dog: Wag wag")
}
func NewDog(color string) Dog {
return Dog{color}
}
func main() {
dog := NewDog("Brown")
dog.MakeNoise()
dog.WagTail()
}

Go "polymorphism"

People are saying, Go is not an OO (Object Oriented) language; don't use OO terms on Go. OK, let me describe what I am able to do with OO --
With an OO language, I can make different animals say different things based on their classes:
cat.Say() // miao
sheep.Say() // bahh
cow.Say() // moo
The same is getting the Area() from Shapes.
However, this go demo code made me believe that it is impossible. Included below as Exhibit#1.
Then today, I found this go demo code, which makes it entirely possible. Included below as Exhibit#2.
So my question is, what's fundamentally different between the two, that makes the first one wrong and second one correct?
How to make the first one "works"?
Exhibit#1:
// Credits: hutch
// https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/0ij9yGHK_8EJ
////////////////////////////////////////////////////////////////////////////
/*
https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/tOO5ZXtwbhYJ
LRN:
Subtype polymorphism: Not applicable (Go doesn't have subtyping).
Although if you embed a struct A implementing interface X into a struct B,
struct B will implement interface X, and can be used instead of struct A in
places where struct A is expected. So, kind of yes.
Robert Johnstone:
interfaces behave similarly to virtual functions, but they are not identical. See the (following) example program by hutch.
*/
package main
import "fmt"
type A struct {
astring string
}
type B struct {
A
bstring string
}
type Funny interface {
strange()
str() string
}
func (this *A) strange() {
fmt.Printf("my string is %q\n", this.str())
}
func (this *A) str() string {
return this.astring
}
func (this *B) str() string {
return this.bstring
}
func main() {
b := new(B)
b.A.astring = "this is an A string"
b.bstring = "this is a B string"
b.strange()
// Output: my string is "this is an A string"
// Many people familiar with OO (and unfamiliar with Go) will be quite
// surprised at the output of that program.
}
Exhibit#2:
// Credits: https://play.golang.org/p/Zn7TjiFQik
////////////////////////////////////////////////////////////////////////////
/*
Problem (From Polymorphism-Subtype.go):
https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/tOO5ZXtwbhYJ
LRN: Subtype polymorphism: Not applicable (Go doesn't have subtyping).
Goal:
This is to demo that "polymorphism" is still doable in Go.
*/
package main
import (
"fmt"
)
type Shape interface {
Area() float32
}
type Point struct {
x float32
y float32
}
// Make sure the structs are different sizes so we're sure it'll work with
// all sorts of types
type Circle struct {
center Point
radius float32
}
func (c Circle) Area() float32 {
return 3.1415 * c.radius * c.radius
}
type Rectangle struct {
ul Point
lr Point
}
func (r Rectangle) Area() float32 {
xDiff := r.lr.x - r.ul.x
yDiff := r.ul.y - r.lr.y
return xDiff * yDiff
}
func main() {
mtDict := make(map[string]Shape)
// No problem storing different custom types in the multitype dict
mtDict["circ"] = Circle{Point{3.0, 3.0}, 2.0}
mtDict["rect"] = Rectangle{Point{2.0, 4.0}, Point{4.0, 2.0}}
for k, v := range mtDict {
fmt.Printf("[%v] [%0.2f]\n", k, v.Area())
}
}
/*
$ go run Polymorphism-Shape.go
[circ] [12.57]
[rect] [4.00]
*/
Your two exhibits are doing different things.
In the first one, B has A embedded in it, and B doesn't implement the strange() method itself, so when you call b.strange(), you get the implementation of strange() defined for A. The receiver (this) of the strange method is b.A, not b, so the value b.A.astring is printed. If you wanted strange to print bstring, you would have to define strange for B.
This points out one of the differences between Go and other OO languages: embedding A within B does not mean that B is a "subclass" of A, so an object of type B cannot be used where an object of type A is expected. However, since B inherits the fields and methods of A, any interface that's implemented by A is also implemented by B, and, unless those methods are defined specifically for B, they operate on the A within B, not B itself.
In the second exhibit, you have the Shape interface which is implemented by the types Circle and Rectangle. The element type of your map is Shape, so any type that implements that interface can be an element in the map. When working with a value of an interface type as you are doing in the loop, you can call any method defined in the interface on the value, and the definition corresponding to the actual type of the value will be called.
First of all I would like to discuss the "impossible" part.
import "fmt"
type Animal interface {
Say() string
}
type Cat struct {}
func (cat Cat) Say() string {
return "miao"
}
type Sheep struct {}
func (sheep Sheep) Say() string {
return "bahh"
}
type Cow struct {}
func (cow Cow) Say() string {
return "moo"
}
func main() {
cat := Cat{}
sheep := Sheep{}
cow := Cow{}
fmt.Println(cat.Say())
fmt.Println(sheep.Say())
fmt.Println(cow.Say())
}
This will work exactly as you would expect. So there is a polymorphism in terms of "different structs responding differently to same method".
The intention of Exhibit#1 demonstrates that what Go does is actually similar to Java castings before #Overrides.
Just add the following method to the first example and see how that will work:
func (this B) strange() {
fmt.Printf("my string is %q\n", this.str())
}

Constructors in Go

I have a struct and I would like it to be initialised with some sensible default values.
Typically, the thing to do here is to use a constructor but since go isn't really OOP in the traditional sense these aren't true objects and it has no constructors.
I have noticed the init method but that is at the package level. Is there something else similar that can be used at the struct level?
If not what is the accepted best practice for this type of thing in Go?
There are some equivalents of constructors for when the zero values can't make sensible default values or for when some parameter is necessary for the struct initialization.
Supposing you have a struct like this :
type Thing struct {
Name string
Num int
}
then, if the zero values aren't fitting, you would typically construct an instance with a NewThing function returning a pointer :
func NewThing(someParameter string) *Thing {
p := new(Thing)
p.Name = someParameter
p.Num = 33 // <- a very sensible default value
return p
}
When your struct is simple enough, you can use this condensed construct :
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33}
}
If you don't want to return a pointer, then a practice is to call the function makeThing instead of NewThing :
func makeThing(name string) Thing {
return Thing{name, 33}
}
Reference : Allocation with new in Effective Go.
There are actually two accepted best practices:
Make the zero value of your struct a sensible default. (While this looks strange to most people coming from "traditional" oop it often works and is really convenient).
Provide a function func New() YourTyp or if you have several such types in your package functions func NewYourType1() YourType1 and so on.
Document if a zero value of your type is usable or not (in which case it has to be set up by one of the New... functions. (For the "traditionalist" oops: Someone who does not read the documentation won't be able to use your types properly, even if he cannot create objects in undefined states.)
Go has objects. Objects can have constructors (although not automatic constructors). And finally, Go is an OOP language (data types have methods attached, but admittedly there are endless definitions of what OOP is.)
Nevertheless, the accepted best practice is to write zero or more constructors for your types.
As #dystroy posted his answer before I finished this answer, let me just add an alternative version of his example constructor, which I would probably write instead as:
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33} // <- 33: a very sensible default value
}
The reason I want to show you this version is that pretty often "inline" literals can be used instead of a "constructor" call.
a := NewThing("foo")
b := &Thing{"foo", 33}
Now *a == *b.
There are no default constructors in Go, but you can declare methods for any type. You could make it a habit to declare a method called "Init". Not sure if how this relates to best practices, but it helps keep names short without loosing clarity.
package main
import "fmt"
type Thing struct {
Name string
Num int
}
func (t *Thing) Init(name string, num int) {
t.Name = name
t.Num = num
}
func main() {
t := new(Thing)
t.Init("Hello", 5)
fmt.Printf("%s: %d\n", t.Name, t.Num)
}
The result is:
Hello: 5
I like the explanation from this blog post:
The function New is a Go convention for packages that create a core type or different types for use by the application developer. Look at how New is defined and implemented in log.go, bufio.go and cypto.go:
log.go
// New creates a new Logger. The out variable sets the
// destination to which log data will be written.
// The prefix appears at the beginning of each generated log line.
// The flag argument defines the logging properties.
func New(out io.Writer, prefix string, flag int) * Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
bufio.go
// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) * Reader {
return NewReaderSize(rd, defaultBufSize)
}
crypto.go
// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
if h > 0 && h < maxHash {
f := hashes[h]
if f != nil {
return f()
}
}
panic("crypto: requested hash function is unavailable")
}
Since each package acts as a namespace, every package can have their own version of New. In bufio.go multiple types can be created, so there is no standalone New function. Here you will find functions like NewReader and NewWriter.
In Go, a constructor can be implemented using a function that returns a pointer to a modified structure.
type Colors struct {
R byte
G byte
B byte
}
// Constructor
func NewColors (r, g, b byte) *Colors {
return &Color{R:r, G:g, B:b}
}
For weak dependencies and better abstraction, the constructor does not return a pointer to a structure, but an interface that this structure implements.
type Painter interface {
paintMethod1() byte
paintMethod2(byte) byte
}
type Colors struct {
R byte
G byte
B byte
}
// Constructor return intreface
func NewColors(r, g, b byte) Painter {
return &Color{R: r, G: g, B: b}
}
func (c *Colors) paintMethod1() byte {
return c.R
}
func (c *Colors) paintMethod2(b byte) byte {
return c.B = b
}
another way is;
package person
type Person struct {
Name string
Old int
}
func New(name string, old int) *Person {
// set only specific field value with field key
return &Person{
Name: name,
}
}
If you want to force the factory function usage, name your struct (your class) with the first character in lowercase. Then, it won't be possible to instantiate directly the struct, the factory method will be required.
This visibility based on first character lower/upper case work also for struct field and for the function/method. If you don't want to allow external access, use lower case.
Golang is not OOP language in its official documents.
All fields of Golang struct has a determined value(not like c/c++), so constructor function is not so necessary as cpp.
If you need assign some fields some special values, use factory functions.
Golang's community suggest New.. pattern names.
I am new to go. I have a pattern taken from other languages, that have constructors. And will work in go.
Create an init method.
Make the init method an (object) once routine. It only runs the first time it is called (per object).
func (d *my_struct) Init (){
//once
if !d.is_inited {
d.is_inited = true
d.value1 = 7
d.value2 = 6
}
}
Call init at the top of every method of this class.
This pattern is also useful, when you need late initialisation (constructor is too early).
Advantages: it hides all the complexity in the class, clients don't need to do anything.
Disadvantages: you must remember to call Init at the top of every method of the class.

How to create a method of a structure in golang that is called automatically?

I have to create a something like a substitute of 2 levels of inheritance in golang, i.e.,
in a package, I have a structure(A), which is inherited(embedded as an anonymous field) by another structure(B) in another package, whose object is to be utilized by the "main" package.
Now, I've created an initializer method for the "B" (BPlease) that returns an object of B (say,B_obj). I can call this initializer(BPlease) from my "main" package at the start of the program.
One of the methods of "B" (say, HelloB()), calls a method of "A"(say,HelloA()) during execution, using "B's" object.
But what I really want is, something like a constructor for "A" that can initialize its fields (preferably when B_obj was created in package "main") before "B" calls any methods of "A".
How to achieve this?
I tried creating an initializer(APlease) for "A" as well and called it (BPlease) to get an object of "A" (A_obj). But I found this object useless as I couldn't utilize it to call "A's" method (HelloA()) inside a method of "B" (HelloB()).
It would be great if someone can tell me how to utilize this object (A_obj).
Here's some code to clarify my query:
package A
type A struct { whatever }
func (A_obj *A) HelloA(){performs some operation...} // a method of A()
func APlease() A {
return A{initialize A fields}
}
-------------------------------------------------------------------------------
package B
type B struct {
A
B fields
}
func BPlease() B {
return B{
A_obj := APlease() // useless to me.... how to utilise this?
initialize B fields}
}
func (B_obj *B) HelloB(){ // a method of B{}
call B_obj.HelloA() // valid as A is an anon field in B struct
some other operations // but A's fields are not initialized for B_obj
...}
---------------------------------------------------
package main
import "B"
import "A"
func main(){
B_obj := B.BPlease() // what I want is, calling this should initialize A's fields for B_obj as well so that when HelloB() calls B_obj.HelloA(), it utilises A's field that have been initialized.
}
I cannot pass all field-values as parameters to B_obj as there are a lot of fields, and also, some field values are generated by calling a method of the same structure.
Regardless of anyone's opinion about fighting the language to have inheritance when it doesn't: No, there are no magic methods, like "getter" or "setter" of whatever. Remotely related (magic powers) are perhaps finalizers, but they're surely not going to help in this case.
However, let me suggest to stop coding language X in Go. Just use Go. Go doesn't use "class-like" inheritance, nor a Go programmer (usually) should. Think of Go like a modernized C. There's no much C code out there relying on inheritance. (OK, I know about GObject ;-)
Some meta-remark: "First structure" and "second structure" make it very hard to understand which one is which. Labeling the different things like A, B and C is the tool which make math so powerful.
Is this your question:
You have two type A and B, B embeds A. You want to make sure B is "fully initialized" in the sense of A is also initialized.
Raw sketch:
type A struct { whatever }
type B struct {
A
more stuff
}
func APlease(params for an A) A {
return A{fields set up from params}
}
func BPlease(params forn an A and for an B) B {
return B{
A: APlease(stuff for A),
more: set from params for B,
}
}
Should do this: You can ask for a proper set up B by calling BPlease with the necessary parameters for both, the embedded A and the rest of B.
To expand on Volker's answer a bit, you should be able to call
func BPlease() B {
a_obj := A.APlease() // initialize the fields of A like normal
b_obj := B{} // create a B, whose anonymous fields are not initialized yet
b_obj.A = a_obj // PERHAPS WHAT YOU WANT: copy all a's fields to b's fields.
// if you are relying sending a_obj's address somewhere in
// APlease(), you may be out of luck.
b_obj.field_unique_to_B = "initialized"
return b_obj
}
Now that you can create B objects with fields initialized by APlease(), you can call A's methods on B's objects, and even call A's methods from within B like so:
func (B_obj *B) HelloB(){
// can't call B_obj.HelloA() like you would expect
B_obj.A.HelloA() // this works. Go "promotes" the anonymous field's methods
// and fields to B_obj
// but they don't appear in B_obj, they appear in B_obj.A
fmt.Printf("And hello from B too; %s", B_obj.field_unique_to_B)
}
I will echo Rick-777 here and suggest you stick to go's naming conventions and idioms; NewReader is much easier to read and understand than ReaderPlease.
I contrived an example that I can put on bitbucket if people want. I think it's much easier to read when you are working with real metaphors; also a disclaimer - this is not the best code, but it does some things that answer your question.
file: car/car.go
package car
import "fmt"
type BaseCar struct {
Doors int // by default, 4 doors. SportsCar will have 2 doors
Wheels int
}
func NewBaseCar() BaseCar {
return BaseCar{Wheels: 4, Doors: 4}
}
// this will be used later to show that a "subclass" can call methods from self.BaseCar
func (c *BaseCar) String() string {
return fmt.Sprintf("BaseCar: %d doors, %d wheels", c.Doors, c.Wheels)
}
// this will be promoted and not redefined
func (c *BaseCar) CountDoors() int {
return c.Doors
}
file sportscar/sportscar.go
package sportscar
// You can think of SportsCar as a subclass of BaseCar. But go does
// not have conventional inheritence, and you can paint yourself into
// a corner if you try to force square c++ structures into round go holes.
import ( "../car" ; "fmt" )
type SportsCar struct {
car.BaseCar // here is the anonymous field
isTopDown bool
}
func NewSportsCar() SportsCar {
conv := SportsCar{} // conv.Wheels == 0
conv.BaseCar = car.NewBaseCar() // now conv.Wheels == conv.Doors == 4
conv.isTopDown = false // SportsCar-only field
conv.Doors = 2 // Fewer Doors than BaseCar
return conv
}
// SportsCar only method
func (s *SportsCar) ToggleTop() {
s.isTopDown = !s.isTopDown
}
// "overloaded" string method note that to access the "base" String() method,
// you need to do so through the anonymous field: s.BaseCar.String()
func (s *SportsCar) String() string {
return fmt.Sprintf("Sports%s, topdown: %t", s.BaseCar.String(), s.isTopDown)
}
file main.go
package main
import ( "./car" ; "./sportscar" ; "fmt")
type Stringer interface { // added this complication to show
String() string // that each car calls its own String() method
}
func main() {
boring := car.NewBaseCar()
fancy := sportscar.NewSportsCar()
fmt.Printf(" %s\n", Stringer(&boring))
fmt.Printf("%s\n", Stringer(&fancy))
fancy.ToggleTop()
fmt.Printf("%s\n", Stringer(&fancy))
fmt.Println("BaseCar.CountDoors() method is callable from a SportsCar:", fancy.CountDoors())
}
There are ways to mimic inheritance in Go if this is what you are looking for, see section "Inheritance" in this blog