This question already has an answer here:
Given:
type Savable interface {}
type Customer struct {} // satisfies 'Savable'
func GetSaved(id string, s Savable) {
// somehow get a reference to the object from cache
s = cachedObject
// alternately, something like:
// json.Unmarshal(jsonFromDisk, &s)
}
func Foo() {
c := Customer{}
GetSaved("bob", &c)
}
Trying a few configurations, I either get compilation errors related to "Expects *Savable, found *Customer", or the GetSaved
function doesn't actually change what I want to be the 'output variable'. Is this doable, and I'm just not getting the right mix of interface/pointers/etc? Or is this not possible for some reason?
Edit: A working example illustrating the problem.
</div>
This works I converted it to bytes and Unmarshaled it back into your structure. Hope this helps. :) package main
import (
"encoding/json"
"fmt"
)
type Savable interface{}
type Customer struct {
Name string
} // satisfies 'Savable'
func GetSaved(id string, s Savable) {
// somehow get a reference to the object from cache
cached := Customer{Name: "Bob"}
byt, _ := json.Marshal(cached)
_ = json.Unmarshal(byt, &s)
}
func main() {
c := Customer{}
GetSaved("bob", &c)
fmt.Println(c)
}
Run link: https://play.golang.org/p/NrBRcRmXRVZ
You can use reflection to set the passed interface. Even when a struct reference is passed as interface, the underlying type info is not lost and we can use reflection.
package main
import (
"fmt"
"reflect"
)
type Savable interface {}
type Customer struct {
Name string
}
func GetSaved(id string, s Savable) {
cached := Customer{ Name: id }
c1 := reflect.ValueOf(cached)
reflect.ValueOf(s).Elem().Set(c1)
}
func main() {
c := Customer{}
fmt.Printf("Before: %v
", c)
GetSaved("bob", &c)
fmt.Printf("After: %v
", c)
}
Here is the running link