<p>So the core idea here is that I want to Unmarshal some JSON and then, given an address within the returned interface{}, retrieve or modify an item at that address. Of course, if someone can point me to something that does this, that'd be great.</p>
<p>I've got the stuff to retrieve a given item at an address together and it works - <a href="http://play.golang.org/p/e_eoZpj_L2" rel="nofollow">http://play.golang.org/p/e_eoZpj_L2</a>. IDK that it's solid or the best thing out there (I'm sure it's not) but it works, and I understand it (even if it does make a ton of allocations).</p>
<p>I however cannot get the stuff to modify an item working - my current code (that is wrong) is:</p>
<pre><code>func SetItem(data *interface{}, target []interface{}, value interface{}) error {
if targetInt, ok := target[0].(int); ok {
if dataSafe, ok := data.(*[]interface{}); ok {
// do stuff to assign for slice
}
} else if targetString, ok := target[0].(string); ok {
if dataSafe, ok := data.(*map[string]interface{}); !ok {
// do stuff to assign for map
}
} else {
return fmt.Errorf("bad address - %s", target)
}
}
func main() {
testBytes := []byte(`{"Everything":"Awesome","Team":{"Everything":"Cool"}}`)
var testData interface{}
err := json.Unmarshal(testBytes, &testData)
err = SetItem(&testData, []interface{}{"Team", "Everything"}, interface{}("Not Cool"))
fmt.Println(testData)
}
</code></pre>
<p>When I run this though I keep getting errors around the same thing - <a href="http://play.golang.org/p/S3mRPg148k" rel="nofollow">http://play.golang.org/p/S3mRPg148k</a></p>
<pre><code>prog.go:11: invalid type assertion: data.(*[]<inter>) (non-interface type *interface {} on left)
prog.go:29: invalid type assertion: data.(*map[string]<inter>) (non-interface type *interface {} on left)
</code></pre>
<p>You must not be able to type assert to a pointer type? Is that correct? Is there a better way to do this while avoiding diving deep into <code>reflect</code>? All in all, I'm stuck, I don't get this, and I wanted to reach out before I got frustrated.</p>
<p><strong>ANY</strong> help is appreciated :-)</p>
<hr/>**评论:**<br/><br/>alexisnotonfire: <pre><p>General note, you almost never want *interface{}, but instead expect interface{} and assert (*sometype)</p>
<p>edit: but i think the bigger question is why are you so keen on using interface? perhaps if you were to try something like <a href="https://mholt.github.io/json-to-go/" rel="nofollow">https://mholt.github.io/json-to-go/</a> to create a struct, your code will be far simpler.</p></pre>jahayhurst: <pre><p>The reality is that I probably don't want a *interface{}, but I want to be able to modify the interface, so I figured I wanted to pass a pointer to the interface.</p>
<p>Still, someone else posted an alternate example that works - so I'll work backwards from that :-)</p></pre>GopherFromHell: <pre><p>take a look here <a href="https://play.golang.org/p/lezghED5N1" rel="nofollow">https://play.golang.org/p/lezghED5N1</a></p></pre>jahayhurst: <pre><p>Thank you so much! :-) I don't know off hand <em>why</em> it works, but I'm so deep in the tank now that having something that does work is enough - I can work backwards from there (and will happily do so).</p>
<p>I have some learning to do, and it looks like I'm going to be digging through more documentation to earn that learning, but I'm ok with doing that. I have a thread to get started with here.</p>
<p>Once again, TY for the help :-) If I only had more upvotes to give...</p>
<p>As a side note: someone downvoted this post. ....Why? Is there something wrong with this? (Other than this generally being very bad idea, or at least a really really shady idea?)</p></pre>GopherFromHell: <pre><p>with some comments and some print statements: <a href="https://play.golang.org/p/c89_CGGFcv" rel="nofollow">https://play.golang.org/p/c89_CGGFcv</a></p>
<p>Usually when parsing JSON the structure (or at least part) is know beforehand, parsing to a struct is much nicer: <a href="https://play.golang.org/p/tmM0x4Ygoy" rel="nofollow">https://play.golang.org/p/tmM0x4Ygoy</a></p>
<p>Of course by your description i assume that it's a more generic case than that</p></pre>natefinch: <pre><p>What are you trying to accomplish? You're asking about why your solution doesn't work, but we don't know what the problem is. </p>
<p>This is probably not the right way to be handling JSON. I'm sure there's a better way. </p>
<p>Explain the problem from the beginning, and then we can probably better help you.</p></pre>jahayhurst: <pre><p>Let me try explaining again:</p>
<p>I'm trying to unmarshal any valid json input into a generic interface{} and then modify a value within it at a given location <em>within that interface [edit]</em> (if that location is valid).</p>
<p>In a more broad sense:</p>
<p>I'm trying to build a binary like curl that will take JSON as input, will send it to a given address, then output the response. However, the API I am working against uses paginated responses - so I want to increment a value at a location within the input until one value in the output is greater than/equal to another - basically work my way through every page of the response.</p>
<p>However, once I get this working, I'll in turn probably use this in at least one other place - pluck values from JSON input and throw them to standard output - and possibly more than that.</p></pre>freeformz: <pre><p>It's probably easier to make a struct the represents the pagination part of the response (to capture the offset / total / length / whatever) and just let JSON unmarshall that. You can use something like a TeeReader (or other golang constructs) to capture a copy of the data for other processing / output.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传