<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 "comma, ok", not "comma, resourceKeysSuccess" :)</p></pre>TheBeasSneeze: <pre><p>It's good practise to always return at the end happy if you can.</p></pre>jerf: <pre><p>In your "particularly ugly" part of the code, the core problem appears to be that you've got a heterogeneous array in Javascript. I'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't ever be heterogeneous because you get this sort of problem in all the "nice" JSON libraries for static type languages. But when you have one, you have one.</p>
<p>You've got two basic options depending on the situation you're in. One is to declare a struct that is the "union" of all the possible structures you may be trying to decode:</p>
<pre><code>type Resource struct {
CommonThing string `json:"commonthing"`
Specialized1 string `json:"special1"`
Specialized2 string `json:"special2"`
}
</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:"special1"`
}
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'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'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're deserializing. (And speaking just for myself, this is where I actually like the statically-typed world'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'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["resource"].([]map[string]interface{})
if success == true {
for _, resource := range arrayOfResources {
for key := range resource {
switch key {
case "aws_instance":
if keys, ok := resource[key].([]map[string]interface{}); ok {
for key := range keys[0] {
if instanceType, ok := keys[0][key].([]map[string]interface{})[0]["instance_type"].(string); ok {
masterResourceMap = countResource(masterResourceMap, key, instanceType)
}
}
}
default:
fmt.Println("resource type not recognized: ", key)
}
}
}
}
</code></pre></pre>bjorn_248: <pre><p>Ah great suggestion, thanks!</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传