Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize a nil pointer struct in method

I have a struct called Article which has a field called Image. Per default Image has value nil. As Image should be only persisted as Image.Id to database I use the bson.BSONGetter, bson.BSONSetter and json.Marshaler interfaces to fake this behavior.

However internally it is possible to use Image as an io.ReadWriteCloser if I load a file onto this with some other helper.

package main

import (
    "io"
    "fmt"

    "gopkg.in/mgo.v2"
)

type Article struct {
    Name  string
    Image *Image
}

type Image struct {
    Id interface{}

    io.ReadWriteCloser
}

func (i *Image) SetBSON(r bson.Raw) error {
    i = &Image{}

    return r.Marshal(i.Id)
}

func (i *Image) GetBSON() (interface{}, error) {
    return i.Id
}

func (i *Image) MarshalJSON() ([]byte, error) {
    return json.Marshal(i.Id)
}

Playground

The problem with this approach now is that it is not possible to initialize Image in Image.SetBSON as Image is nil.

like image 917
bodokaiser Avatar asked May 15 '26 04:05

bodokaiser


1 Answers

The receiver is passed by value, including the pointer receiver: it is a copy, and changing its value doesn't change the initial pointer receiver on which the method is called.

See "Why are receivers pass by value in Go?".

A function Setup returning a new *Foo would work better: play.golang.org

func SetUp() *Foo {
    return &Foo{"Hello World"}
}

func main() {
    var f *Foo
    f = SetUp()
}

Output:

Foo: <nil>
Foo: &{Bar:Hello World}

twotwotwo points to a better convention in the comments, which is to make a package function foo.New(), as in sha512.New().
But here, your Setup() function might do more than just creating a *Foo.

like image 165
VonC Avatar answered May 18 '26 06:05

VonC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!