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 <kultig...@gmail.com > <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 golang-nuts...@googlegroups.com <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 golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.