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.

Reply via email to