How do I avoid typecasting so much?

blov · · 485 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I posted this on the codereview stackexchange here: <a href="https://codereview.stackexchange.com/questions/160044/how-can-i-avoid-typecasting-so-much" rel="nofollow">https://codereview.stackexchange.com/questions/160044/how-can-i-avoid-typecasting-so-much</a>.</p> <p>I thought I would post it here as well to cast a wider net and perhaps get more feedback. My main concern lies with all the typecasting I am doing, as outlined in the post, but any and all advice is appreciated.</p> <hr/>**评论:**<br/><br/>UniverseCity: <pre><p>First off, your code would be more readable with less nesting. e.g. rather than this </p> <pre><code>if success { ... success code } </code></pre> <p>try </p> <pre><code>if !success { return } ... success code </code></pre> <p>Besides that, less type casting is all about better defining your data to be able to encapsulate them in structs with proper named fields.</p></pre>f2f: <pre><p>the code can benefit from some overall brevity. the pattern is called &#34;comma, ok&#34;, not &#34;comma, resourceKeysSuccess&#34; :)</p></pre>TheBeasSneeze: <pre><p>It&#39;s good practise to always return at the end happy if you can.</p></pre>jerf: <pre><p>In your &#34;particularly ugly&#34; part of the code, the core problem appears to be that you&#39;ve got a heterogeneous array in Javascript. I&#39;m inferring that from the type you are using; if the array is not heterogeneous then the solution is a better type on the object you are decoding into.</p> <p>As a matter of style, JSON arrays really shouldn&#39;t ever be heterogeneous because you get this sort of problem in all the &#34;nice&#34; JSON libraries for static type languages. But when you have one, you have one.</p> <p>You&#39;ve got two basic options depending on the situation you&#39;re in. One is to declare a struct that is the &#34;union&#34; of all the possible structures you may be trying to decode:</p> <pre><code>type Resource struct { CommonThing string `json:&#34;commonthing&#34;` Specialized1 string `json:&#34;special1&#34;` Specialized2 string `json:&#34;special2&#34;` } </code></pre> <p>Then decode into that type, switch on the key, and use the fields directly. As I wrote that, that at least gives you field access. You can even give yourself methods by using struct composition:</p> <pre><code>type Specialized1 struct { Specialized1 string `json:&#34;special1&#34;` } func (s1 Specialized1) Method() { ... } type Resource struct { Specialized1 Specialized2 } </code></pre> <p>This can get a bit funky if you have a lot of shared fields, though. If you don&#39;t mind a bit of a pileup you can put all the methods on this object.</p> <p>Alternatively, you can use <code>json.RawMessage</code> as the type you&#39;re deserializing into, then wait to figure out what kind of struct to finally unmarshal it into once you actually know. That takes a bit more code, but recovers the ability to have any methods you want on the objects you&#39;re deserializing. (And speaking just for myself, this is where I actually like the statically-typed world&#39;s way of handling JSON better than the dynamic languages. The dynamic languages have a much easier story for taking a piece of JSON and just reading it, but it&#39;s generally a bigger hassle to get that JSON into objects that have methods you can call.)</p></pre>ytrtyrhjgfytrghfjth: <pre><p>well it all starts when creating your maps. Ask yourself if those many interface{} have to be empty interfaces.</p> <p>The core go team seems to encourage coders to use longer lines rather than more lines. Those type assertions could be wrapped into if ok statements.</p> <p>shorter variables names, shorter but still useful.</p> <pre><code>arrayOfResources, success := decodedOutput[&#34;resource&#34;].([]map[string]interface{}) if success == true { for _, resource := range arrayOfResources { for key := range resource { switch key { case &#34;aws_instance&#34;: if keys, ok := resource[key].([]map[string]interface{}); ok { for key := range keys[0] { if instanceType, ok := keys[0][key].([]map[string]interface{})[0][&#34;instance_type&#34;].(string); ok { masterResourceMap = countResource(masterResourceMap, key, instanceType) } } } default: fmt.Println(&#34;resource type not recognized: &#34;, key) } } } } </code></pre></pre>bjorn_248: <pre><p>Ah great suggestion, thanks!</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

485 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传