我有一个名为Article
的结构,其中有一个名为Image
的字段。默认情况下,Image
的值为nil
。由于Image
应仅作为Image.Id
保留到数据库,因此我使用bson.BSONGetter
,bson.BSONSetter
和json.Marshaler
接口来伪造此行为。
然而,如果我使用其他帮助程序将文件加载到此文件中,则可以在内部使用Image
作为io.ReadWriteCloser
。
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)
}
现在这种方法存在的问题是,由于Image
为Image.SetBSON
,因此无法在Image
中初始化nil
。
答案 0 :(得分:3)
接收器是 passed by value ,包括指针接收器:它是一个副本,并且更改其值不会更改调用该方法的初始指针接收器。
请参阅“Why are receivers pass by value in Go?”。
返回新* Foo的函数Setup
可以更好地运行:play.golang.org
func SetUp() *Foo {
return &Foo{"Hello World"}
}
func main() {
var f *Foo
f = SetUp()
}
输出:
Foo: <nil>
Foo: &{Bar:Hello World}
twotwotwo指向一个更好的约定in the comments,即制作包函数foo.New()
,如sha512.New()
中所示。
但是在这里,您的Setup()
功能可能不只是创建*Foo
。
答案 1 :(得分:1)
bson.Unmarshal
在bson数据中遇到Image
值时会创建一个指针。因此,一旦我们输入SetBSON
i
已经是指向Image
结构的有效指针。这意味着您没有理由分配Image
。
package main
import (
"fmt"
"io"
"gopkg.in/mgo.v2/bson"
)
type Article struct {
Name string
Image *Image `bson:"image,omitempty"`
}
type Image struct {
Id interface{}
AlsoIgnored string
io.ReadWriteCloser
}
func (i *Image) SetBSON(r bson.Raw) error {
err := r.Unmarshal(&i.Id)
return err
}
func (i Image) GetBSON() (interface{}, error) {
return i.Id, nil
}
func main() {
backAndForth(Article{
Name: "It's all fun and games until someone pokes an eye out",
Image: &Image{
Id: "123",
AlsoIgnored: "test",
},
})
backAndForth(Article{Name: "No img attached"})
}
func backAndForth(a Article) {
bsonData, err := bson.Marshal(a)
if err != nil {
panic(err)
}
fmt.Printf("bson form: '%s'\n", string(bsonData))
article := &Article{}
err = bson.Unmarshal(bsonData, article)
if err != nil {
panic(err)
}
fmt.Printf("go form : %#v - %v\n", article, article.Image)
}
http://play.golang.org/p/_wb6_8Pe-3
输出是:
bson form: 'Tname6It's all fun and games until someone pokes an eye outimage123'
go form : &main.Article{Name:"It's all fun and games until someone pokes an eye out", Image:(*main.Image)(0x20826c4b0)} - &{123 <nil>}
bson form: 'nameNo img attached'
go form : &main.Article{Name:"No img attached", Image:(*main.Image)(nil)} - <nil>