Is there a constructor interface for a struct type? - go

In golang, say I have a type that needs some setup done on it before use beyond just setting default values. ex:
type dice struct {
input string
count int
sides int
result int
}
func (d *dice) Roll() {
//initialize random seed
rand.Seed(time.Now().UnixNano())
for i := 0; i < d.count; i++ {
d.result = d.result + rand.Intn(d.sides)+1)
}
}
Simple example but say if I wanted to have d.Roll() called automatically when creating an instance of the 'dice' type is there a way to do that? More in line with the issue I'm trying to solve, say I wanted the rand.Seed(time.Now().UnixNano()) bits to be called automatically before I call Roll() is there an idiomatic golang way to do this?
Basically "How do you handle constructor functionality in golang?" is my question. Is there an interface for this I can add?

No, Go doesn't provide this kind of interface. You just can't use a constructor like you would do in C++ by example.
The current idiom is to create a function
NewX(args...) X // or *X
in which you can setup your struct as you want. In your case, it could look like this:
func NewDice() dice {
var d dice
d.Roll()
return d
}

There is not. But the common, and I would say idiomatic, thing to do is to put a func NewDice() dice in your package and then you can just call it to get an instance. Do your set up there. It serves the same purpose as a constructor. It's pretty common to have package level methods like NewMyType that do initilization and return and instance.

Related

How to distinguish between reference and value in golang

package main
type A struct {
Num int
}
func getA() A {
return A{Num: 10}
}
func main() {
if getA().Num == 10 {
// getA().Num = 20 // why not working
myA := getA()
myA.Num = 20
}
}
why "getA().Num = 20" line do not working?
I'm don't know the difference between
myA := getA()
myA.Num = 20
and
//getA().Num = 20 // why not working
I think it just two line and one line...
I'm more familiar with Java.
What I need to know to understand it?
I expected the code working correctly....
Tweak your function declaration like this, and it will work as you're expecting:
func getA() *A {
return &A{Num: 10}
}
What has changed is that getA returns a pointer to a value of type A.
In Java, class data types are always used as references (like a pointer), except the language doesn't use an explicit notation like this. So, writing Go code to use pointer types like *A is similar to what you're used to in Java.
The part that may confuse you is that Java doesn't have a direct equivalent for Go's non-pointer types, like the plain A in your Go code. In Java, you can only declare a class type, which always acts as a reference.

Can I get a variable of a type based on reflect.Type [duplicate]

I have a function which takes an interface, like this:
func method(data interface{})
.. because I need to process different structs which have common fields/methods. In this function I use data tens or hundreds of times, in different places. It's really unpleasant to add switch a.(type) { case .. case .. all the time.
Is there a way to create a variable with just one switch with needed type and then just use this variable everywhere later? Something like:
var a .... // something here
switch data.(type) {
case *Struct1:
a = data.(*Struct1)
case *Struct2:
a = data.(*Struct2)
}
// Continue with 'a' only
a.Param = 15
fmt.Println(a.String())
Go is a statically typed language, the type of a must be known at compile time. And since Go does not support generics yet, you can't do what you want.
Try to come up with some other solution, e.g. abstract away the things you want to do with a into an interface, and have the concrete types implement that interface. Then a can be a variable of this interface type, and you can call methods of it.
If you can achieve this, actually you can even change the parameter of the data type to this interface, and no type assertion or type switch is needed.
Alternatively you could use reflection to access common fields (either for get or set) identified by their name, but reflection provides no compile-time guarantee, and it's usually less efficient. For an example how to do that, see this question: Assert interface to its type
You can't do what you ask for in your question directly, go is statically typed, so you can't have one variable that can hold different types, and still access that variable as if it is typed.
If you're only working on the common struct fields in your method, you are perhaps better off gathering all the common variables in its own struct, illustrated below as the commons struct and have your method take that type as an argument
package main
import (
"fmt"
)
type commons struct {
name string
age int
}
type structA struct {
commons
other_stuff int
}
type structB struct {
commons
foo string
}
func method(c* commons) {
fmt.Println(c)
c.age +=1
}
func main() {
a := structA{commons{"foo", 44}, 1}
b := structB{commons{"bar", 33}, "test"}
method(&a.commons)
method(&b.commons)
fmt.Println(a)
}
Go playground
I can't figure out what is your real goal but if the "method" you want to write handles common fields from similar structures, and you cannot fix original structures using Type Embedding, as #nos said above, then you can try to make another structure for method-internal use:
var v Vehicle // with common fields
switch data.(type) {
case *Car:
v.Handle = data.(*Car).Handle // or CircleHandle
case *Motorcycle:
v.Handle = data.(*Motorcycle).Handle // or BarHandle
}
v.Degree = 15
v.Speed = 50
v.Direction = "left"
v.Style = "rough"
/// so many things on `v`...
steering(v)
I think it is not a good approach but sometimes... :-)

How to create a variable with needed type instead of type assertion

I have a function which takes an interface, like this:
func method(data interface{})
.. because I need to process different structs which have common fields/methods. In this function I use data tens or hundreds of times, in different places. It's really unpleasant to add switch a.(type) { case .. case .. all the time.
Is there a way to create a variable with just one switch with needed type and then just use this variable everywhere later? Something like:
var a .... // something here
switch data.(type) {
case *Struct1:
a = data.(*Struct1)
case *Struct2:
a = data.(*Struct2)
}
// Continue with 'a' only
a.Param = 15
fmt.Println(a.String())
Go is a statically typed language, the type of a must be known at compile time. And since Go does not support generics yet, you can't do what you want.
Try to come up with some other solution, e.g. abstract away the things you want to do with a into an interface, and have the concrete types implement that interface. Then a can be a variable of this interface type, and you can call methods of it.
If you can achieve this, actually you can even change the parameter of the data type to this interface, and no type assertion or type switch is needed.
Alternatively you could use reflection to access common fields (either for get or set) identified by their name, but reflection provides no compile-time guarantee, and it's usually less efficient. For an example how to do that, see this question: Assert interface to its type
You can't do what you ask for in your question directly, go is statically typed, so you can't have one variable that can hold different types, and still access that variable as if it is typed.
If you're only working on the common struct fields in your method, you are perhaps better off gathering all the common variables in its own struct, illustrated below as the commons struct and have your method take that type as an argument
package main
import (
"fmt"
)
type commons struct {
name string
age int
}
type structA struct {
commons
other_stuff int
}
type structB struct {
commons
foo string
}
func method(c* commons) {
fmt.Println(c)
c.age +=1
}
func main() {
a := structA{commons{"foo", 44}, 1}
b := structB{commons{"bar", 33}, "test"}
method(&a.commons)
method(&b.commons)
fmt.Println(a)
}
Go playground
I can't figure out what is your real goal but if the "method" you want to write handles common fields from similar structures, and you cannot fix original structures using Type Embedding, as #nos said above, then you can try to make another structure for method-internal use:
var v Vehicle // with common fields
switch data.(type) {
case *Car:
v.Handle = data.(*Car).Handle // or CircleHandle
case *Motorcycle:
v.Handle = data.(*Motorcycle).Handle // or BarHandle
}
v.Degree = 15
v.Speed = 50
v.Direction = "left"
v.Style = "rough"
/// so many things on `v`...
steering(v)
I think it is not a good approach but sometimes... :-)

GoLang conventions - create custom type from slice

Is it a good idea to create own type from a slice in Golang?
Example:
type Trip struct {
From string
To string
Length int
}
type Trips []Trip // <-- is this a good idea?
func (trips *Trips) TotalLength() int {
ret := 0
for _, i := range *trips {
ret += i.Length
}
return ret
}
Is it somehow a convention in Golang to create types like Trips in my example? Or it is better to use []Trip in the whole project? Any pros and cons?
There's no convention, as far as I am aware of. It's OK to create a slice type if you really need it. In fact, if you ever want to sort your data, this is pretty much the only way: create a type and define the sort.Interface methods on it.
Also, in your example there is no need to take the address of Trips since slice is already a "fat pointer" of a kind. So you can simplify your method to:
func (trips Trips) TotalLength() (tl int) {
for _, l := range trips {
tl += l.Length
}
return tl
}
If this is what your type is (a slice), it's just fine. It gives you an easy access to underlying elements (and allows for range iteration) while providing additional methods.
Of course you probably should only keep essential set of methods on this type and not bloating it with everything that would take []Trip as an argument. (For example I would suggest having DrawTripsOnTheGlobe(t Trips) rather than having it as a Trips' method.)
To calm your mind there are plenty of such slice-types in standard packages:
http://golang.org/pkg/net/#IP
http://golang.org/pkg/sort/#Float64Slice
http://golang.org/pkg/sort/#IntSlice
http://golang.org/pkg/encoding/json/#RawMessage

In golang, how do I re-assign an external reference from within a function?

I'm probably not expressing this correctly in the question, but perhaps this code will make it clearer:
package main
import "fmt"
type Blob struct {
Message string
}
func assign1(bb **Blob) {
*bb = &Blob{"Internally created by assign1"}
}
func (b *Blob) assign2() {
*b = Blob{"Internally created by assign2"}
}
func main() {
x1 := &Blob{"Hello World"}
assign1(&x1)
fmt.Printf("x1 = %+v\n", *x1)
x2 := Blob{"Hello World"}
x2.assign2()
fmt.Printf("x2 = %+v\n", x2)
}
Produces, as desired:
x1 = {Message:Internally created by assign1}
x2 = {Message:Internally created by assign2}
I want to pass a reference (pointer to a pointer) into a function and have the function assign a new value to the pointer such that the calling scope will see that new value.
I've figured out the above two ways of doing this, but I'd like to know if they are actually correct or if there is some hidden flaw. Also, are either of them more idiomatic than the other?
Coming from Java, assign2 just seems wrong but I'm sure I've seen something similar in the encoding/json package. What is that actually doing?
Thanks!
James answers the mechanics of assign2. I'll touch a bit on when to use it.
Let's take a simpler example, first.
type Counter uint
func (c *Counter) Increment() {
*c += 1
}
In the counter example the entire state of the receiver is changing. Similarly for the encoding/json package the entire state of the receiver is changing. That's really the only time I would use that style.
One major advantage of the style: you can define an interface for the change, just like the GobDecoder does.
When I first saw the assign2 style it was a little grating. But then I remembered that (c *Counter) Increment gets translated to Increment(c *Counter) in the machine code and it didn't bother me anymore. I personally prefer assign1-style. (Though, there is no need for the double pointers as orignally posted.)
package main
import "fmt"
type Blob struct {
Message string
}
func assign1(b *Blob) {
*b = Blob{"Internally created by assign1"}
}
func main() {
x1 := Blob{"Hello World"}
assign1(&x1)
fmt.Printf("x1 = %+v\n", *x1)
}
Both forms are valid Go, as you've discovered.
For the assign2 case, the compiler finds that assign2 does not appear in Blob's method set, but it is part of *Blob's method set. It then converts the method call to:
(&x2).assign2()
While it can be confusing if a method then goes and changes x2 like in your example, there are a number of places in the standard library where this pattern is used. Probably the most common one is implementing custom decoding for a type with the encoding/json module: you implement the DecodeJSON method with a pointer receiver, and update the value being pointed to.

Resources