<p>Hi everyone!<br/>
noob question here as I'm taking the Go tour on the website. My main languages are Python and Java (although I know a bit of Rust).<br/>
Now, I understand how to use pointers, but as I was going through the pointers section of the tour I was wondering:<br/>
if we can initialize structs this way </p>
<pre><code>s := &MyStruct{1,2}
</code></pre>
<p>what's the point of having the standard constructor? Or viceversa, what's the point of this constructor?<br/>
I know there's a reason why this is allowed, I just don't get it. Could someone explain it? :)</p>
<hr/>**评论:**<br/><br/>mdaffin: <pre><p>Standard constructor? Go has no constructors, just methods that can return objects constructed by the method you showed.</p>
<p>You normally prefer to wrap that syntax in a method as it is a little nicer to look at and you can add validation or change the default values that are return.</p></pre>levnikmyskin: <pre><p>Thanks for your reply! What I meant by standard constructor is the fact that we can write </p>
<pre><code>s := &MyStruct{1,2}
s2 := MyStruct{1,2}
</code></pre>
<p>So my question was about these two initializers (how are they called?). Why and when should I use one instead of the other?</p></pre>mdaffin: <pre><blockquote>
<p>s := MyStruct{1,2}</p>
</blockquote>
<p>Is the initalizer</p>
<blockquote>
<p>s2 := &THING</p>
</blockquote>
<p>Is taking a point of something so</p>
<blockquote>
<p>s2 := &MyStruct{1,2}</p>
</blockquote>
<p>Is taking a point to a struct created by the initalizer. It is bascially equlivent to doing</p>
<blockquote>
<p>s := MyStruct{1,2}
s2 := &s</p>
</blockquote>
<p>You use & when you want a pointer and don't use it when you don't want a pointer.#</p>
<p><em>Edit: fixed my terminology</em></p></pre>levnikmyskin: <pre><p>Yeah this was pretty clear to me. I understand the use case of pointers like: </p>
<pre><code>n := 3
p := &n
</code></pre>
<p>However we cannot write something like: </p>
<pre><code>n := &3
</code></pre>
<p>because this just doesn't make sense at a memory level, and I understand that. The problem with structs is that you can actually call: </p>
<pre><code>s1 := &MyStruct{1,2}
s2 := &MyStruct{3,4}
fmt.Println(s1, s2)
</code></pre>
<p>this is perfectly legal, and you can edit those two MyStruct instances values independently. This is what I don't understand </p>
<p>Edit: nevermind, got it. So basically when you use the & initializer, it is equivalent to first declare it and then pointing to it. Thank you for your explanation! </p></pre>Garovix: <pre><p>So does Go have constructors or it doesn't have them? You confused me with your first reply</p></pre>mdaffin: <pre><p>Sorry, I was being a bit flippant with my terminology. Go has no formal/special constructors like other languages do. No custom code is run when you call <code>new</code> and there is no special init function for types.</p>
<p>You can initialize values, <code>s := MyStruct{}</code> or <code>s := 2</code> and you have normal methods that can wrap around initializers. <code>func NewMyStruct() MyStruct { ... }</code>. Both can be referred to as constructors, mostly the latter it is more accurate to say the former is an initializer.</p>
<p>According to the language, there is no special meaning to constructor methods, it is just a term people used to describe them.</p></pre>Garovix: <pre><p>Oh thanks</p></pre>metamatic: <pre><p><code>&MyStruct{}</code> isn't a constructor, because it doesn't cause any kind of initialization code to run. It's a struct literal, just like <code>17</code> is an integer literal and <code>"cheesecake"</code> is a string literal.</p>
<p>If you want a constructor, the usual Go style is to create a <code>func NewMyStruct() *MyStruct {}</code> method.</p></pre>jackmott2: <pre><p>A lot of people have explained the semantics of constructor but I don't think you got an answer as to why you would sometimes want a struct, and sometimes a pointer to a struct.</p>
<p>Being able to control how you use memory is one of the most important things you can do to control the performance of programs on modern hardware, and choosing when you want a pointer and when you don't is part of that. </p>
<p>For example if you have an array of MyStructs, where MyStruct contains an X and a Y, it would look like this in memory:</p>
<pre><code>[X,Y,X,Y,X,Y,X,Y]
</code></pre>
<p>The Xs and Ys would all be contiguous in your computers memory, which if you needed to often iterate over them and change them, would lets this be done very quickly.</p>
<p>Conversely, if you had an array of pointers to mystructs, the array would contain just pointers, and each pointer would point to a relatively random position in your computers memory. This means your CPU's caches will not as easily be leveraged to grab those mystructs from ram quickly, and iterating over an array and reading or writing those mystructs would be much much slower. It is a good experiment to try for yourself. In Java for instance, where you have no choice, the array would always be pointers to your classes, and performance suffers when you have to do that.</p>
<p>Another time when you might want a pointer is if your struct has many fields, passing the struct to functions means making a copy of all of those fields, which can get expensive. When passing a pointer to a struct you pass only 1 word to the function.</p>
<p>Lastly you might chose one or the other for the semantics of how your code should operate. If you pass a struct to a function, and that function modifies the struct, it is modifying a copy, not the original struct you passed it. Sometimes that is desired. Other times you might want it to be working with the original. In that case you need to pass a pointer.</p>
<p>As others have explained the struct initializer is the same in either case, The & is applied to it like any other variable, to get an address of the struct.
Hope that helps!</p></pre>levnikmyskin: <pre><p>Thank you really! This was a really good and clear explanation. Having never worked with pointers on a serious level, I was struggling to grasp these kinds of low level differences. I'll definitely try the array of struct thing! Thanks :D</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传