Is reflect.StructOf buggy or am I on drugs?

agolangf · · 472 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Before I make a bug report, can I borrow some extra eyes to see if I haven&#39;t misunderstood something?</p> <p>The code in question is <a href="https://gist.github.com/art4711/d71803a210f1d6458a4c311a8b2fb31f">here, runnable with go test</a></p> <p>Let&#39;s not go into why I&#39;m doing this, it&#39;s probably a bad idea anyway, but I went down the rabbit hole. I wanted to implement interface X with reflection and the code tests various methods to implement interface X. This has been tested and behaves the same with Go 1.9 and 1.10.1.</p> <ol> <li><code>TestSimple</code> is just a simple smoke test of if Y implements X, it does.</li> <li><code>TestAnonStructNonPtr</code>, anonymous struct that embeds Y. Implements X and works.</li> <li><code>TestReflectNonPtr</code>, should be the same as AnonStructNonPtr, but implemented using reflect.StructOf. Does not implement X (the generated type has no exported methods at all).</li> <li><code>TestReflectPtr</code>, replace Y with *Y in the struct generated by reflection. Implements X. But wait a minute. Fair enough that it implements X, but shouldn&#39;t <code>reflect.New</code> create a zero value of the struct? The embedded pointer should be nil and we should crash in <code>x.Set</code>, but we don&#39;t.</li> <li><code>TestAnonStructPtr</code> tests if I&#39;m on drugs. Same as above, but as an anonymous struct, not reflect.StructOf. Implements X and crashes in Set, just like expected (I&#39;m not on drugs).</li> <li><code>TestAnonStructPtr2</code> just like above, but correctly initializing the pointer. Implements X and works.</li> </ol> <p>Did I miss something? And I mean mostly point 4 as the main issue. Who initialized that pointer?</p> <hr/>**评论:**<br/><br/>TheMerovius: <pre><p>First: The playground can <a href="https://play.golang.org/p/el7siQFprxp" rel="nofollow">run tests too</a>. For your actual question, see <a href="https://github.com/golang/go/issues/15924" rel="nofollow">this issue</a>.</p></pre>hegbork: <pre><p>I&#39;ve seen that issue. It&#39;s related, but it&#39;s not the same. I was actually thinking about adding this to that issue if I&#39;m not misreading my code somehow.</p> <p>The weirdness here is that a pointer seems to somehow become initialized by the call to New or (more likely) by a call to my method. I really can&#39;t explain it by anything I understand of how things should work, hence the question if I&#39;m on drugs and missed something obvious. (yeah, I should have made it more clear that it&#39;s step 4 that&#39;s the weird thing).</p> <p>Oh, and thanks for the playground pointer. I just pasted the code in there and when it complained about the package name I just assumed that it wouldn&#39;t run tests.</p></pre>TheMerovius: <pre><p>I believe you are right and you found a bug in reflect. I took the liberty of <a href="https://github.com/golang/go/issues/24782" rel="nofollow">reporting it</a> with a minimum working example and some additional info. It would be great if you could butt in there :)</p> <p>I also reported <a href="https://github.com/golang/go/issues/24781" rel="nofollow">this issue</a>, which I found while trying to figure out what was going wrong ^^ It seems, reflect with embedded fields is pretty broken, sadly :(</p></pre>hegbork: <pre><p>The only semi-rational explanation I have is that the pointer doesn&#39;t get magically allocated. Instead whatever mechanism implements the methods actually treats the struct field as a proper embedded field and not a pointer and what gets allocated is the actual string. Of course, internally in reflect things are still confused and that&#39;s why printf and such lie.</p> <p>This hypothesis might sound far-fetched, but memory doesn&#39;t just allocate itself spontaneously.</p> <p>Edit: oh, and that&#39;s exactly what the code in your issue shows. The pointer gets set to the actual value you&#39;re setting.</p></pre>

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

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