Hi Burak,
The example objects are very simplified. In real code, there are many more
object types and some of them looks exactly same. For instance;
type chromeHomepage struct {
Url string
File string
}
type firefoxHomepage struct {
Url string
File string
}
They look exactly same in the json, but clean method for firefox and chrome
objects are completely different.
On Tuesday, February 20, 2018 at 1:03:51 AM UTC+1, Burak Serdar wrote:
>
> On Mon, Feb 19, 2018 at 4:45 PM, Doğan Kurt <[email protected]
> <javascript:>> wrote:
> > 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.
>
>
> You can use an intermediate structure to parse the JSON input, and
> then process that to construct the slice:
>
> var entry []struct {
> Name string
> Size int
> ..
> }
>
> json.Unmarshal(&entry)
> for _,e:=range entry {
> if len(e.Name)==0 {
> ... // This entry has size, create struct exe
> } else {
> ... // This entry has name, create struct Browser
> }
> }
>
> Of course, this assumes you can deduce the type of the element based
> on its contents easily.
>
>
> >
> > 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] <javascript:>.
> > For more options, visit https://groups.google.com/d/optout.
>
--
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.