Inheritance syntax. What is the difference? - go

In Go what is the difference below?
I tried to search, but I couldn't think of a right term to describe them. How are they officially called?
#1 - Parent inside struct:
type MyTime struct {
time.Time
}
#2 - Parent right after my type without struct definition:
type MyTime time.Time
For #2, I can initialize my type with another time.Time like mt := MyTime(t).
How to initialize #1 type with another time.Time variable?

Go is not an object oriented language, there is no type hierarchy and inheritance. For details, see What is the idiomatic way in Go to create a complex hierarchy of structs? and Go embedded struct call child method instead parent method.
Your first example creates a new type MyTime embedding time.Time. By embedding a type, all fields and methods of the embedded type gets promoted and are available as if they were fields or methods of the embedder type, very handy when you want to implement an interface for example (because the promoted methods will "exist" without having to declare them).
You can instantiate it like (for details, see Golang embedded struct type):
t := MyTime{Time: time.Now()}
Your second example creates a new type, all methods will be stripped from it. This comes handy when you do not want the existing methods to be part of the new type. A shining example of this is to define the String() method or override marshaling behavior when you want to call the original behavior in your implementation, for details see Call json.Unmarshal inside UnmarshalJSON function without causing stack overflow. You can create a value of it using a simple type conversion:
t := MyTime(time.Now())

Related

Golang reflect get nil pointer underlying type

I would like to know if there is a way to "cast" a nil pointer of a struct into the (empty) struct itself using reflection or anything else.
My method parameters are an empty parent struct as an interface, a field name as a string and the field value as an interface.
The point is to get the real type of the field by going through the parent struct until I find the field matching the given name. I cannot just get the type of the value, because there will be cases where it won't return the correct type (for example a time.Time will be seen as a string).
The method can take any struct as parent, which is why it takes interfaces as parameters.
My problem is that the parent struct that is given is always a empty one (it serves only as a model), with default values. So fields that are pointers to substructs are nil. So to find the field given as parameter, I have to get the underlying substruct instead of the nil pointer to continue the search inside.
I cannot find a way to achieve that, I am not sure if that's even possible.
Any help is welcomed.

Calling an exported method on a unexported field

I know, similar questions have been asked, but I found no answer for that case:
type ExportedStruct struct{ //comes from a dependency, so I can't change it
unexportedResource ExportedType
}
I want to call an exported method Close() on unexportedResource.
What I did was:
rs := reflect.ValueOf(myExportedStructPtr).Elem() //myExportedStructPtr is a pointer to an ExportedStruct object
resourceField := rs.FieldByName("unexportedResource")
closeMethod := resourceField.MethodByName("Close")
closeMethod.Call([]reflect.Value{reflect.ValueOf(context.Background())})
, which results in reflect.flag.mustBeExported using value obtained using unexported field.
This is quite annoying since I want to run more than one test which utilizes ExportedStruct, but I can't as long as the underlying resource is not used.
Since I can access private fields (as explained here) I have a bit hope that I'm allowed to access the public method of that field somehow, too. Maybe I'm just reflecting wrong?
Unexported fields are for the declaring package only. Stop messing with them. They are not for you.
The linked answer can only access it by using package unsafe, which is not for everyday use. Package unsafe should come with a "not to touch" manual.
If you do need to access unexportedResource, make it exported. Either the field, or add a method to the type that calls unexportedResource.Close(). Or add a utility function to the package that does this (functions in the same package can access unexported fields and identifiers).
While #icza's answer gives you reason why you should not do it, here is a way of how to do it using reflect and unsafe:
var t pkg.T
v := reflect.ValueOf(&t).Elem()
f := v.FieldByName("t")
rf := reflect.NewAt(f.Type(), unsafe.Pointer(f.UnsafeAddr())).Elem()
rf.MethodByName("Print").Call(nil)
playground: https://play.golang.org/p/CmG9e4Bl9gg
I am afraid that what you are trying to do is impossible through reflection.
Below is the implementation of reflect.Call:
func (v Value) Call(in []Value) []Value {
v.mustBe(Func)
v.mustBeExported()
return v.call("Call", in)
}
As you can see there is an explicit check (i.e. mustBeExported()) if Value was obtained from an exported field or not.
Typically there is a reason why fields are not exported. If you want to manipulate that field you will have to use methods implemented by the ExportedStruct struct.
If you can modify the code where ExportedStruct is defined, you can easily implement a wrapper Close method on that. For example:
type ExportedStruct struct{
unexportedResource ExportedType
}
func (e ExportedStruct) Close(){
e.unexportedResource.Close()
}

How to write idiomatic constructor

I'm confused about the constructors in Go. Most constructors I've seen return a struct, but 'Effective Go' suggests that an interface can be returned in some cases, according to the rule of 'Generality'.
I trust 'Effective Go' to provide good ideas, but this doesn't seem to follow the principle of 'accept interfaces, return structs'. I guess that many types implement an interface and nothing more than that, so in that case it would be common to see constructors which return interfaces.
Another related statement is that interfaces should be defined by the consumer, but 'Generality' means that the interface is defined by the producer.
Can someone clarify?
As it has already been mentioned, returning an interface should be considered something exceptional.
Returning errors of type error which is an interface is one of those exception.
Returning an interface that represents an unexported type is the other exception. But why would you have an exported interface that describes an unexported struct instead of just having an exported struct?
The reason is simple, that allows you a higher degree of control on how that struct is constructed.
Compare this two pieces of code:
type MyType struct {
MyField string
}
func NewMyType(value string) MyType {
return MyType{value}
}
func (t MyType) MyMethod() string {
return t.MyField
}
type MyType interface {
MyMethod() string
}
type myType struct {
MyField string
}
func NewMyType(value string) MyType {
return myType{value}
}
func (t myType) MyMethod() string {
return t.MyField
}
In the first case I would be able to do: myVar := MyType{} while in the second case I won't be able to do so, I am forced to use the provided constructor. The first case also allows to modify the field value after creation which is not allowed in the second case. Making the field unexported will solve the second part but not the first.
This example is obviously trivial, but being able to construct invalid structs may have a horrible impact. By having specific constructors you can ensure that the object is in a valid starting state and you will only need to make sure it always stays in a valid state. If you can't ensure that, you may need to check that it is in a valid state at the start of every method.
For example consider a DB request. It needs a DB connection. If the user is able to create a DB request without a DB connection you will have to check that it is valid in every method. If you enforce him to use a constructor you can check at creation time and done.
It depends a bit on your preference and how you view things. Coming from OOP background my take is: there is no point in the constructor if you cannot enforce it. Adding the constructor means - you must supply these values when instantiating this item. If your struct is public, it will be misused and instantiated bypassing the constructor. So it makes sense that the constructor returns the public interface and the struct is private (lowercase). If the struct is public, there is no point in the constructor, because you cannot enforce it. Writing code is a dialogue between writer and reader, making a struct public and having a constructor would tell the reader - here you have the constructor, but you also have a public struct and that would mean that constructor usage is arbitrary. If that is the case, go with that setup
In most cases constructor functions return concrete types (or pointer to a type).
The situations in which returning interfaces might be a good idea is when calling factory functions or builder functions in which underlying concrete type satisfies that interface.
Consider error interface for example, when you call http.NewRequest underlying concentrate error type can be of net.Error, net.DNSError etc. Now try to think how are you going to create an api like this without an error interface if function returns concrete type? Only solution to it I can think of is to create a massive error type for net package and add fields for extra information, but its most probably much harder to maintain, test that kind of error type and not to mention memory bloat.
Whether you choose to return concrete type or an interface is a design choice, some guidelines exists to give solution to common scenarios.

Why use non-struct types in Golang? [duplicate]

I am actually learning golang (from .NET) and there is one thing I don't understand about this language.
Sometimes I find this kind of declaration:
https://github.com/golang/crypto/blob/master/ed25519/ed25519.go
// PublicKey is the type of Ed25519 public keys.
type PublicKey []byte
What does it mean exactly?
Is it a creating a struct which inherit from []byte?
Is it just an alias?
I thought golang forbid inheritance.
It's a type declaration, more specifically a type definition. It creates a new type, having []byte as its underlying type:
A type definition creates a new, distinct type with the same underlying type and operations as the given type, and binds an identifier to it.
New types are created because they can simplify using them multiple times, their identifier (their name) may be expressive in other contexts, and–most importantly–so that you can define (attach) methods to it (you can't attach methods to built-in types, nor to anonymous types or types defined in other packages).
This last part (attaching methods) is important, because even though instead of attaching methods you could just as easily create and use functions that accept the "original" type as parameter, only types with methods can implement interfaces that list ("prescribe") those methods, and as mentioned earlier, you can't attach methods to certain types unless you create a new type derived from them.
As an example, the type []int will never implement the sort.Interface required to be sortable (by the sort package), so a new type sort.IntSlice is created (which is type IntSlice []int) to which the required methods are attached, so you can pass a value of type sort.IntSlice to the sort.Sort() function but not a value of type []int. Since sort.IntSlice has []int as its underlying type, if you have a value of []int, you can simply convert it to sort.IntSlice if you want to sort it, like in this example (try it on the Go Playground):
is := []int{1,3,2}
sort.Sort(sort.IntSlice(is))
fmt.Println(is) // Prints: [1 2 3]
When you create a new type, there is no "inheritance" involved. The new type will have 0 methods. If you want "inheritance-like" functionality, you should check out embedding (in relation with struct types), in which case the embedder type will also "have" the methods of the embedded type.

Go: Embedding a primitive type?

Suppose we have this piece of code:
type User struct {
int32
Name string
}
Can this type of embedding be useful?
Does int32 have any methods which other can call on instances of User?
How can I access the value of the int32 that User is embedding?
The type int32 is a predeclared type, it has no methods. To verify:
fmt.Println(reflect.TypeOf(int32(0)).NumMethod()) // Prints 0
You can refer to all embedded fields by using the unqualified type name as the field name (Spec: Struct types), predeclared types are no exception. See this example:
u := User{3, "Bob"}
fmt.Printf("%#v\n", u)
u.int32 = 4
fmt.Println(u.int32)
Output (try it on the Go Playground):
main.User{int32:3, Name:"Bob"}
4
Primary gain of using embedding is:
methods of the embedded type get promoted, so it's easier to implement interfaces (you don't need to provide methods that get promoted)
you can "override" methods of the embedded type (on the embedder type): provide your own implementation which will be called when a value of your embedder type is used
and fields of the embedded type get promoted, so code is shorter to refer to promoted fields (field name is left out).
By embedding predeclared types such as int32, you don't get any advantage over using just a regular field (named, not embedded field), as the int32 type doesn't have any methods or fields.
Going forward, besides not having any advantage, you even have a disadvantage. Since predeclared type names start with lowercased letters, embedding them implicitly makes them unexported, so you can only refer to them in the declaring package of the embedder type. If you make them regular, named fields, you may choose to use an uppercased name to make it exported, or a lowercased name to make it unexported.

Resources