Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can embedded methods access "parent" fields?

Tags:

go

Background

I've done a fair amount of spec reading and code testing and I think the answer is no, but I want to make sure I'm not missing anything.

Goal

Basically, I'm trying to create a Active Record style ORM for Go, because I like how readable it is and how abstracted it is from its back end data store. I'd rather write user.Save() than data.Save(user) by embedding common CRUD methods on the user struct.

Example

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

Question

Is there a way to make top-level fields (not sure what the correct term in Go is for these) accessible from embedded methods (eg: s.Name or s.Method()?

Thank you donating your time to a new Gopher.

like image 439
Brenden Avatar asked Nov 23 '13 21:11

Brenden


1 Answers

Go doesn't provide any support for what you're after: the receiver of your Test method is a Bar pointer, and there is no way to tell whether it is embedded or not.

If you really want to go this route, one option would be to add an interface{} member to Bar and require that types that it be set to the containing type. Initialising this member could either be the responsibility of whoever created the value, or perhaps require callers to pass the value to some ORM method to set it. This isn't particularly pretty, but it's probably the best you can do.

With that out of the way, is it really that bad to structure the API as db.Save(user) rather than user.Save()? The former offers an obvious way to extend to multiple databases, while the latter seems more likely to rely on global state.

like image 156
James Henstridge Avatar answered Nov 11 '22 12:11

James Henstridge