一尘不染

嵌入式方法可以访问“父”字段吗?

go

背景

我已经做了大量的规范阅读和代码测试,我认为答案是否定的,但是我想确保自己没有遗漏任何东西。

目标

基本上,我正在尝试为Go创建Active
Record样式的ORM,因为我喜欢它的可读性以及从后端数据存储中抽象出来的方式。我宁愿写,也user.Save()不愿data.Save(user)在用户结构上嵌入常见的CRUD方法。

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()

谢谢您将时间捐赠给新的Gopher。


阅读 220

收藏
2020-07-02

共1个答案

一尘不染

Go不会为您提供任何支持:Test方法的接收者是一个Bar指针,并且无法判断它是否被嵌入。

如果您确实想走这条路,一种选择是将一个interface{}成员添加到其中,Bar并要求将其类型设置为包含类型。初始化此成员可能是创建值的人的责任,或者可能要求调用者将值传递给某些ORM方法进行设置。这不是特别漂亮,但是可能是您可以做的最好的事情。

有了这样的方法,将API构造为db.Save(user)而不是真的很糟糕user.Save()吗?前者提供了一种扩展到多个数据库的明显方法,而后者似乎更可能依赖于全局状态。

2020-07-02