What meaning of (*SomeStruct)(nil)? - go

I'm trying to understand this piece code of an ORM library, but I cannot understand what is meaning of (*User)(nil)? First parenthesis is a pointer to User struct, then what is 2nd parenthesis stand for?
type User struct {
Id int64
Name string
Emails []string
}
for _, model := range []interface{}{(*User)(nil), (*Story)(nil)} {
err := db.CreateTable(model, &orm.CreateTableOptions{
// ....
}
}

In Go, nils can by typed, so that a nil of the type *User is different from a nil of the type *Story. So (*User)(nil) is actually a type conversion that makes a typed nil pointer. Further more, the typed pointer is then implicitly converted to interface{} according to the CreateTable signature. Interfaces always store their type along with the data, and that information can be accessed in runtime using reflect, like it happens in ORM.
Because in Go types are not "first-class citizens", i.e. you can't just pass a type around as a value, they use a typed nil pointer idiom that essentially allows providing the desired model type as an argument to CreateTable without creating an instance of it or messing with reflect in the client code.

Related

Using empty interfaces in go

I am trying to understand the code that is used at my company. I am new to go lang, and I have already gone through the tutorial on their official website. However, I am having a hard time wrapping my head around empty interfaces, i.e. interface{}. From various sources online, I figured out that the empty interface can hold any type. But, I am having a hard time figuring out the codebase, especially some of the functions. I will not be posting the entire thing here, but just the minimal functions in which it has been used. Please bear with me!
Function (I am trying to understand):
func (this *RequestHandler) CreateAppHandler(rw http.ResponseWriter, r *http.Request) *foo.ResponseError {
var data *views.Data = &views.Data{Attributes: &domain.Application{}}
var request *views.Request = &views.Request{Data: data}
if err := json.NewDecoder(r.Body).Decode(request); err != nil {
logrus.Error(err)
return foo.NewResponsePropogateError(foo.STATUS_400, err)
}
requestApp := request.Data.Attributes.(*domain.Application)
requestApp.CreatedBy = user
Setting some context, RequestHandler is a struct defined in the same package as this code. domain and views are seperate packages. Application is a struct in the package domain. The following two structs are part of the package views:
type Data struct {
Id string `json:"id"`
Type string `json:"type"`
Attributes interface{} `json:"attributes"`
}
type Request struct {
Data *Data `json:"data"`
}
The following are part of the package json:
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
func (dec *Decoder) Decode(v interface{}) error {
if dec.err != nil {
return dec.err
}
if err := dec.tokenPrepareForDecode(); err != nil {
return err
}
if !dec.tokenValueAllowed() {
return &SyntaxError{msg: "not at beginning of value"}
}
// Read whole value into buffer.
n, err := dec.readValue()
if err != nil {
return err
}
dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
dec.scanp += n
// Don't save err from unmarshal into dec.err:
// the connection is still usable since we read a complete JSON
// object from it before the error happened.
err = dec.d.unmarshal(v)
// fixup token streaming state
dec.tokenValueEnd()
return err
}
type Decoder struct {
r io.Reader
buf []byte
d decodeState
scanp int // start of unread data in buf
scan scanner
err error
tokenState int
tokenStack []int
}
Now, I understood that, in the struct Data in package views, Application is being set as a type for the empty interface. After that, a pointer to Request in the same package is created which points to the variable data.
I have the following doubts:
What exactly does this keyword mean in Go? What is the purpose of writing this * RequestHandler?
Initialization of a structure in Go can be done while assigning it to a variable by specifying the values of all it's members. However, here, for the struct Data, only the empty interface value is assigned and the values for the other two fields are not assigned?
What is the advantage of assigning the Application struct to an empty interface? Does it mean I can use the struct members using the interface variable directly?
Can someone help me figure out the meaning of this statement? json.NewDecoder(r.Body).Decode(request)?
While I know this is too much, but I am having a hard time figuring out the meaning of interfaces in Go. Please help!
this is not a keyword in go; any variable name can be used there. That is called the receiver. A function declared in that way must be called like thing.func(params), where "thing" is an expression of the type of the receiver. Within the function, the receiver is set to the value of thing.
A struct literal does not have to contain values for all the fields (or any of them). Any fields not explicitly set will have the zero value for their types.
As you said, an empty interface can take on a value of any type. To use a value of type interface{}, you would use type assertion or a type switch to determine the type of the value, or you could use reflection to use the value without having to have code for the specific type.
What specifically about that statement do you not understand? json is the name of a package in which the function NewDecoder is declared. That function is called, and then the Decode function (which is implemented by the type of the return value of NewDecoder) is called on that return value.
You may want to take a look at Effective Go and/or The Go Programming Language Specification for more information.

Why does golang prohibit assignment to same underlying type when one is a native type?

Consider this code:
package main
import "fmt"
type specialString string
func printString(s string) {
fmt.Println(s)
}
// unlike, say, C++, this is not legal GO, because it redeclares printString
//func printString(s specialString) {
// fmt.Println("Special: " + s)
//}
func main() {
ss := specialString("cheese")
// ... so then why shouldn't this be allowed?
printString(ss)
}
My question is: why is the language defined so that the call to printString(ss) in main() is not allowed? (I'm not looking for answers that point to the Golang rules on assignment; I have already read them, and I see that both specialString and string have the same 'underlying type' and both types are 'named' -- if you consider the generic type 'string' to be named, which Golang apparently does -- and so they are not assignable under the rules.)
But why are the rules like that? What problem is solved by treating the built-in types as 'named' types, and preventing you from passing named types to all the standard library functions that accepting the same underlying built-in type? Does anybody know what the language designers had in mind here?
From my point of view, it seems to create a lot of pointless type conversion in the code, and discourages the use of strong typing where it actually would make sense..
I believe the initial authors' logic here is that named type is named for a reason - it represents something different, not just underlying type.
I guess I've read it somewhere in golang-nuts, but can't remember exact discussion.
Consider the following example:
type Email string
You named it Email, because you need to represent e-mail entity, and 'string' is just simplified representation of it, sufficient for the very start. But later, you may want to change Email to something more complex, like:
type Email struct {
Address string
Name string
Surname string
}
And that will break all your code that work with Email implicitly assuming it's a string.
This is because Go does not have class inheritance. It uses struct composition instead. Named types do not inherit properties from their underlying type (that's why it's not called "base type").
So when you declare a named type specialString with an underlying type of a predefined type string, your new type is a completely different type from the underlying one. This is because Go assumes you will want to assign different behaviors to your new type, and will not check its underlying type until run-time. This is why Go is both a static and dynamic language.
When you print
fmt.Println(reflect.TypeOf(ss)) // specialString
You get specialString, not string. If you take a look at Println() the definition is as follows:
func Println(a ...interface{}) (n int, err error) {
return Fprintln(os.Stdout, a...)
}
This means you can print any predeclared types (int, float64, string) because all of them implements at least zero methods, which makes them already conform to the empty interface and pass as "printable", but not your named type specialString which remains unknown to Go during compile time. We can check by printing the type of our interface{} against specialString.
type specialString string
type anything interface{}
s := string("cheese")
ss := specialString("special cheese")
at := anything("any cheese")
fmt.Println(reflect.TypeOf(ss)) // specialString
fmt.Println(reflect.TypeOf(s)) // string
fmt.Println(reflect.TypeOf(at)) // Wow, this is also string!
You can see that specialString keeps being naughty to its identity. Now, see how it does when passed into a function at run-time
func printAnything(i interface{}) {
fmt.Println(i)
}
fmt.Println(ss.(interface{})) // Compile error! ss isn't interface{} but
printAnything(ss) // prints "special cheese" alright
ss has become passable as interface{} to the function. By that time Go has already made ss an interface{}.
If you really want to understand deep down the hood this article on interfaces is really priceless.
It's called nominal typing. It simply means that the type is identified by it's name and it has to be made explicit to be useful.
From a convenience point of view it is easy to critique but it super useful.
For example, let's say you have a parameter to a function that is a string but it cannot be just any string, there are rules you need to check. If you change the type from string to something that implies that you checked the string for potential problems you made a good design decision because it's now clear from just looking at the code that the string needs to go via some function to validate the input first (and enrich it's type in the process).
type Validated string
func Validate(input string): (Validated, err) {
return Validated(input), nil // assuming you actually did validate the string
}
Go makes these tradeoffs because it does improve readability (i.e. the ability of someone unfamiliar with your code to quickly understand how things work) and that's something they (the Go language designers) value above all else.

Passing different structs to a function (GO)?

I have a function like the following for querying a mongo database:
func findEntry(db, table string, entry *User, finder *bson.M) (err error) {
c := mongoSession.DB(db).C(table)
return c.Find(finder).One(entry)
}
I'd like to reuse the function for structs other than "User", by passing in a pointer to any instantiated struct object - just not quite sure of the proper semantics to do this. I think that I should be able to do this by making the 'entry' parameter an interface{} and then I'd need to use reflection to 'cast' it back to the original struct so the One() function call could properly fill in the struct on the call? Is there a 'better' way to accomplish this (please no flaming about lack of generics, I'm just looking for a practical solution using best practices).
Use this function:
func findEntry(db, table string, entry interface{}, finder bson.M) error {
c := mongoSession.DB(db).C(table)
return c.Find(finder).One(entry)
}
and call it like:
var user User
err := findEntry("db", "users", &user, bson.M{"name": "John"})
The type information for user is passed through findEntry to the One method. There's no need for reflection or a "cast" in findEntry.
Also, use bson.M instead of *bson.M. There's no need to use a pointer here.
I created an example on the playground to show that the type information is passed through findEntry.

dereference pointer to DB in struct

Usually when I see a field declared on a struct it's without a pointer or a dereferenced pointer symbol *, however in several code snippets where I've seen a database field in a struct it's with a pointer dereference as you see below. Why is that necessary?
type DB struct {
*bolt.DB
}
func Open(path string, mode os.FileMode) (*DB, error) {
db, err := bolt.Open(path, mode)
if err != nil {
return nil, err
}
return &DB{db}, nil
}
or a dereferenced pointer symbol *
That is the norm, for complex non-value type, in order to avoid making a copy.
See Golang book "Pointers" for example of struct with pointer(s) in them.
return &DB{db}
That returns a pointer to the newly created DB instance.
As noted in "Can you “pin” an object in memory with Go?":
Note that, unlike in C, it's perfectly OK to return the address of a local variable; the storage associated with the variable survives after the function returns
From "Pointer/Value Subtleties":
Go is also pass by value, but it has both pointers and value types. Pointers refer to a certain memory location, and allow you to mutate the data at that location
For more, see "Best practice “returning” structs in Go?"
Use pointers for big structs or structs you'll have to change, and otherwise use values, because getting things changed by surprise via a pointer is confusing.

Golang calling methods on interface pointer

I am using Gorp for database access, Gorp has a standard DbMap type, as well as a Transaction type for when you want to be able to roll back. Both types implement the SqlExecutor interface.
I am therefore programming against the SqlExecutor interface, so I can use transactions if I want without needing to change my code.
I then initialise a Gorp DbMap or Transaction and pass it in as a field property. The problem is that I need a pointer to the Gorp "object", else how will I be able to roll back if I use a Transaction if the Gorp "object" is passed by value instead of reference.
I then get a message such as
r.Gorp.Get undefined (type *gorp.SqlExecutor has no field or method Get)
when I try use my code. How do I call the methods?
A code sample is below.
package repositories
import (
"github.com/coopernurse/gorp"
)
type Repository struct {
Gorp *gorp.SqlExecutor // <<<< Need pointer so I can rollback
}
func (r *Repository) GetById(i interface{}, key interface{}) interface{} {
obj, err := r.Gorp.Get(i, key)
if err != nil {
panic(err)
}
return obj
}
Maybe you are overthinking the problem, or you may still be under a "call by reference" influence from another language:
gorp.SqlExecutor is an interface and you will never use a pointer to an interface value. Never ever. (Technically this is untrue, but if you actually need a pointer to an interface, you will have mastered Go enough to understand why "never ever" is a really good advice.)
Never think about "call by reference". There is no such thing in Go. Passing a pointer to a function is not "call by reference". Leave that behind.
I assume you did not try to use transactions and do rollbacks on the non-pointer-to-interface code?
Background: In Go, you pass around a pointer to something because of two reasons:
1) You want to, because your struct is really large and you want to avoid copying, or
2) you need to, because the callee wants to modify the original (this is typical for methods with a pointer receiver).
Now an interface value is really tiny (just two words) so reason 1, to pass a pointer to an interface value, does not apply. Reason 2 does not apply in most cases as passing a pointer to an interface value will allow you to change the interface value itself, but most often you would like to modify the value stored inside the interface value. This value stored inside the interface value often is a pointer value which allows to change the value of a struct by calling methods on an interface value which wraps a pointer to this struct. This sounds complicated but isn't: The novice Go programmer just doesn't use pointers to interfaces (as this won't do any good) and the experienced Go programmer doesn't use pointers to interfaces (as it won't do much good) unless he needs to modify an interface value, typically during reflection.
gorp.SqlExecutor is an interface and you will never use a pointer
to an interface value. Never ever.
If this is your goal, you're going about it incorrectly. An
interface is a wrapper, and a contract that guarantees behavior. If
your interface requires that the methods mutate the implementing
type, then the implementing type should be a pointer. A pointer to
the interface itself will not suddenly make the implementing type
mutable.
Your struct should be
type Repository struct {
Gorp gorp.SqlExecutor
}
func (r *Repository) GetById(i interface{}, key interface{}) interface{} {
obj, err := r.Gorp.(gorp.SqlExecutor).Get(i, key)
if err != nil {
panic(err)
}
return obj
}

Resources