Hi great Go community. Sorry it's a long question, but i would really
appreciate some guidance.
--------------------
Let's say i have two different objects, browser and executable that
implement ScanCleaner interface.
type ScanCleaner interface {
scan()
clean()
}
type browser struct {
Name string
}
type exe struct {
Size int
}
These two objects are different internally but they implement the same scan and
clean methods. In general i don't need to know their internals. I have this
instead;
var objects []ScanCleaner
I can iterate through the objects, scan and clean them. So far so good, but
i want to decouple scan and clean processes. One can scan the system, get a
report and later clean based on that report file. So that interface slice
should be stored appropriately in a file and recovered later.
I encode the objects slice, and get a perfectly good json output.
Here is the working code: https://play.golang.org/p/cYgnhgxkPL0
Output: [{"Name":"chrome"},{"Name":"firefox"},{"Size":1234},{"Size":4321}]
--------------------
The problem arises when i need to decode report file and recover the
objects interface slice. Object types are completely lost.
My current solution is this; I encapsulate every object with a string that
specifies it's type,
type detection struct {
Type string
Object ScanCleaner
}
and encode the slice of detection instead. The Type string is main.exe or
main.browser obtained by fmt.Sprintf("%T", obj).
Here is a working code: https://play.golang.org/p/KeJjl8IOqRP
Output:
[{"Type":"main.browser","Object":{"Name":"chrome"}},{"Type":"main.exe","Object":{"Size":1234}}]
Finally, i use a dispatch routine that recognizes objects type by Type string,
decodes the object with the correct type, and calls it's clean method.
func cleanAll(jsn []byte) {
detects := []struct {
Type string
Object json.RawMessage
}{}
json.Unmarshal(jsn, &detects)
for _, d := range detects {
var sc ScanCleaner
switch d.Type {
case "main.exe":
var e *exe*
json.Unmarshal(d.Object, &e)
sc = e
case "main.browser":
var b *browser*
json.Unmarshal(d.Object, &b)
sc = b
}
sc.clean()
}
}
Here is the final working code: https://play.golang.org/p/HpHFiHrT2oz
Output:
browser clean {chrome}
browser clean {firefox}
exe clean {1234}
exe clean {4321}
--------------------
This solution is obviously not good. If i change an objects name, i should
change the Type string in switch. Also i need to rely on the string
returned by fmt.Sprintf("%T").
Is there a better solution to accomplish this task?
Thanks.
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.