背景
我已经做了大量的规范阅读和代码测试,我认为答案是否定的,但是我想确保自己没有遗漏任何东西。
目标
基本上,我正在尝试为Go创建Active Record样式的ORM,因为我喜欢它的可读性以及从后端数据存储中抽象出来的方式。我宁愿写,也user.Save()不愿data.Save(user)在用户结构上嵌入常见的CRUD方法。
user.Save()
data.Save(user)
例
package main import ( "fmt" "reflect" ) func main() { test := Foo{Bar: &Bar{}, Name: "name"} test.Test() } type Foo struct { *Bar Name string } func (s *Foo) Method() { fmt.Println("Foo.Method()") } type Bar struct { } func (s *Bar) Test() { t := reflect.TypeOf(s) v := reflect.ValueOf(s) fmt.Printf("model: %+v %+v %+v\n", s, t, v) fmt.Println(s.Name) s.Method() }
http://play.golang.org/p/cWyqqVSKGH
题
有没有一种方法可以使嵌入式方法(例如:s.Name或)访问顶级字段(不确定Go中正确的术语是什么)s.Method()?
s.Name
s.Method()
谢谢您将时间捐赠给新的Gopher。
Go不会为您提供任何支持:Test方法的接收者是一个Bar指针,并且无法判断它是否被嵌入。
Test
Bar
如果您确实想走这条路,一种选择是将一个interface{}成员添加到其中,Bar并要求将其类型设置为包含类型。初始化此成员可能是创建值的人的责任,或者可能要求调用者将值传递给某些ORM方法进行设置。这不是特别漂亮,但是可能是您可以做的最好的事情。
interface{}
有了这样的方法,将API构造为db.Save(user)而不是真的很糟糕user.Save()吗?前者提供了一种扩展到多个数据库的明显方法,而后者似乎更可能依赖于全局状态。
db.Save(user)