<p>Before I make a bug report, can I borrow some extra eyes to see if I haven'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's not go into why I'm doing this, it'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'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't.</li>
<li><code>TestAnonStructPtr</code> tests if I'm on drugs. Same as above, but as an anonymous struct, not reflect.StructOf. Implements X and crashes in Set, just like expected (I'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've seen that issue. It's related, but it's not the same. I was actually thinking about adding this to that issue if I'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't explain it by anything I understand of how things should work, hence the question if I'm on drugs and missed something obvious. (yeah, I should have made it more clear that it's step 4 that'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'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'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's why printf and such lie.</p>
<p>This hypothesis might sound far-fetched, but memory doesn't just allocate itself spontaneously.</p>
<p>Edit: oh, and that's exactly what the code in your issue shows. The pointer gets set to the actual value you're setting.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
0 回复
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传