Help understanding pointers

xuanbao · · 543 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I am looking at: <a href="https://tour.golang.org/methods/2">https://tour.golang.org/methods/2</a> and <a href="https://tour.golang.org/methods/3">https://tour.golang.org/methods/3</a></p> <p>On line 18 on page 2, it looks like this: <code>f := MyFloat(-math.Sqrt2)</code></p> <p>On line 22 on page 3, it looks like this: <code>v := &amp;Vertex{3, 4}</code></p> <p>I can take the ampersand out and it looks like this: <code>v := Vertex{3, 4}</code> and it still runs without an issue.</p> <p>I fully understand pointers/references when calling method, but why use the pointer to a struct/type instead of just using the type?</p> <hr/>**评论:**<br/><br/>casba: <pre><p>When you just use the type, you&#39;re passing a copy of the object to the method. When you use a pointer to the type, the method operates on the actual object you fired the method on.</p> <p>See here: <a href="http://play.golang.org/p/eTcdlGt6MI">http://play.golang.org/p/eTcdlGt6MI</a></p></pre>pyr0t3chnician: <pre><p>Ok, I understand all that. My concern is line 23: <code>f := Thing{x:3};</code></p> <p>Why not <code>f := &amp;Thing{x:3};</code> instead?</p></pre>Niriel: <pre><p>Passing references around instead of copying values should be seen as a performance/memory optimization. Mutating variables is source of many bugs and is never formally required. So it makes sense to pass everything by value and copy everything, you don&#39;t take the address of anything and you save yourself some pain; the computer won&#39;t mind doing the tedious job of copying. Once the code is correct, one may think about saving cpu and ram if needed.</p></pre>bmurphy1976: <pre><p>Often times copying will be faster because you won&#39;t be allocating variables on the heap and thus triggering the garbage collector. It&#39;s hard to intuit what will actually perform better. As always you should profile first before optimizing and err on the side of creating clean consistent code. Only optimize when you have proven you need it.</p></pre>hjianhao: <pre><p>f := &amp;Thing {x:3} , f is a pointer, point to a Thing object</p> <p>f := Thing {x:3}, f is a Thing object.</p> <p>f := Thing{x:3} is literal initialization, no value copy exist. So there is no performance problem.</p> <p>var f Thing</p> <p>f := Thing{x:3}</p> <p>This is value copy, so it has performance problem.</p></pre>Fwippy: <pre><p>I think it&#39;s largely a matter of style - I try to use types that match the receiver signature, so that I&#39;m more aware of &#34;this is a pointer&#34; or &#34;this will get a copy&#34;.</p> <p>There are performance considerations, but they&#39;re not worth thinking about before you have a performance issue, profile your code, and find out that line is in your bottleneck.</p></pre>hjianhao: <pre><p>I think it&#39;s bad for Go to use such style. I think the receiver should always be the pointer. User can make the function not to modified receiver by add decoration like &#34;const&#34;, just like C++ does. By this way, developer need not worry about performance issue caused by value copy.</p></pre>bkeroack: <pre><p>type conversion (since MyFloat is defined to be a float64):</p> <pre><code>f := MyFloat(-math.Sqrt2) </code></pre> <p>In the above, &#34;f&#34; can be used anywhere that a MyFloat is expected, but must be converted back to a float64 wherever float64 is expected.</p> <pre><code>v := &amp;Vertex{3, 4} </code></pre> <p>As others have stated, pointers to structs are most useful when you know you will need to pass a reference to the struct to some function. By default, the struct will be passed by value (ie, a copy of the struct) which is both less efficient and potentially broken if the function is expected to modify the struct such that the calling function can see the changes.</p></pre>dominikh: <pre><p><a href="https://golang.org/ref/spec#Calls:" rel="nofollow">https://golang.org/ref/spec#Calls:</a></p> <blockquote> <p>If x is addressable and &amp;x&#39;s method set contains m, x.m() is shorthand for (&amp;x).m():</p> </blockquote></pre>mc_hammerd: <pre><p>how i think of it is like this:</p> <ul> <li><code>&amp;</code> is address-of </li> <li><code>*</code> is im trying to use this var (and its a pointer)</li> </ul> <p>so its two different paradigms (ways of writing code)</p> <p>with pointers you can do this</p> <pre><code> func plus(v *int) { *v++ } x := 9 plus(&amp;x) Println(x) // 10 </code></pre> <p>without pointers</p> <pre><code>func plus(v int) { v++ } x := 9 plus(x) Println(x) // 9 ... x is still 9 only the local variable v incremented </code></pre> <p>without pointers (works)</p> <pre><code>func plus(v int) int { v++; return v } x := 9 x = plus(x) Println(x) // 10 </code></pre></pre>

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

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