Learning Go, run into an odd problem I can't seem to spot...

agolangf · · 407 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>:edit: Solved! Thanks go out to <a href="/u/aboukirev">/u/aboukirev</a>, for educating me on how range works. Glad I posted it, I almost didn&#39;t because I was so convinced I was just being blind to something stupid and non-go-specific, but it turns out I just misunderstood the mechanics of range, and wasn&#39;t expecting it to return a copy rather than a reference. Maybe I should have - everything seems to be copy-by-default in Go, but the Range page on gobyexample wasn&#39;t explicit about it like it was in other cases. :/edit:</p> <p>Been a while since I did any significant programming, and even longer since I did it in C/C++ or any similar, lowish-level language. Decided for fun to dust off the old brain and learn Go, which I quite liked the look and sound of when it emerged.</p> <p>Anyway. With no particular goal beyond dicking around and learning Go, started throwing together a program. Everything was going fine... until I hit this issue. </p> <p>The error I was getting was &#34;index out of range.&#34; After poking it with a stick a bit, I found the error started happening when I changed any of my loops from C-style &#34;i:=0;i&lt;n;i++&#34; loop to using range. Note that I had switched from an array to a slice, with the intention of making the size variable - but have not yet done so. </p> <p><a href="https://pastebin.com/e8LKnzmC">This version works</a>, and <a href="https://pastebin.com/4EsDnvU5">this one doesn&#39;t.</a></p> <p>The only changes between the two are the loop at line 164, where it loops over the worms calling update. Oh, and the panic test is commented out in the broken one, so that it throws the actual error. </p> <p>The error is actually thrown from the Update method at line 81, when called from main after the first timer tick at 200. Further poking and some debug-panics revealed that, at that time, the len of the worms body slice has been 0&#39;d. Update was called - repeatedly - on the worms before that, and none of the code should ever shrink the body slices, only grow them. </p> <p>Old C/C++ debugging PTSD is screaming that this is probably just something stupid somewhere else, which these changes just happen to be triggering somehow, and that if I take a step back I&#39;ll probably spot it quickly tomorrow - but I&#39;ve gone full-obsessive that I <em>will</em> figure out what&#39;s wrong before I walk away from this computer. So, if someone else can see it, and save me from pounding my head against it until something breaks, I&#39;ll be grateful. </p> <p>Any other suggestions or abuse on my go coding style and practices, etc. are, of course, welcome as well. Been doing go for all of an afternoon now, so I&#39;m sure I&#39;m doing everything wrong in any case.</p> <hr/>**评论:**<br/><br/>Zikes: <pre><p>An idiom I heard somewhere and has saved me a fair amount of headache is &#34;never take the pointer of a <code>range</code> value&#34;. By running <code>w.Init</code>, defined as <code>func (w *Worm) Init</code>, you&#39;re effectively doing just that.</p> <p>Change your range from <code>for _, w := range worm</code> to <code>for i, _ := range worm</code> and then use <code>worm[i].Init</code>, and that should work.</p></pre>GopherAtl: <pre><p>thanks, aboukirev&#39;s comment beat you by a few minutes and pointed me to the error in my thinking. Didn&#39;t even occur to me that range might be returning copies rather than references to the array items.</p></pre>aboukirev: <pre><p>Have not looked thoroughly but just FYI <code>range</code> returns copies of values so you are not going to <code>Init</code> elements in slice but copies of them. And the slice you allocate is a slice of Worm not of *Worm so you are not operating pointers but whole objects.</p> <p>You should be able to figure the rest.</p></pre>GopherAtl: <pre><p>aah! Thanks, that is definitely the problem! I was convinced it was gonna be something really derpy I was doing but I decided to post it in case it was some go-specific detail (like this) that I just didn&#39;t know - and now I do. </p></pre>

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

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