TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

There is no pass by reference in Go

130 pointsby micah_chattabout 8 years ago

14 comments

jasodeabout 8 years ago
An extended explanation missing from Dave Cheney&#x27;s answer is that the &quot;reference&quot; etymology has at least 2 meanings. This is why his explanation is virtually the same as the one 20 years ago in the C Language FAQ[1] compiled by Steve Summit.<p>- &quot;reference&quot; definition 1: an alias that cannot be null which is what a &quot;reference type&quot; is in Pascal and C++. This might be thought of as a stricter &quot;computer-science&quot; definition. The C and Go languages don&#x27;t have this type of &quot;reference&quot;.<p>- &quot;reference&quot; definition 2: a pointer variable that lets programmers change the <i>&quot;thing pointed to&quot;</i> instead of the pointer variable itself to avoid copying unnecessary bytes. This is the colloquial usage. It also doesn&#x27;t help that we call the star operator the &quot;de-REFERENCING&quot; operator[2] instead of the &quot;de-POINTERIZING&quot; operator. (What are we &quot;derefencing&quot; if it&#x27;s not a &quot;reference&quot;?!?)<p>Cheney is talking about definition 1.<p>[1] <a href="http:&#x2F;&#x2F;www.di-srv.unisa.it&#x2F;~vitsca&#x2F;LAB&#x2F;C-faq.html" rel="nofollow">http:&#x2F;&#x2F;www.di-srv.unisa.it&#x2F;~vitsca&#x2F;LAB&#x2F;C-faq.html</a> excerpt:<p><pre><code> 4.11: Does C even have &quot;pass by reference&quot;? A: Not really. Strictly speaking, C always uses pass by value. You can simulate pass by reference yourself, by defining functions which accept pointers and then using the &amp; operator when calling, and the compiler will essentially simulate it for you when you pass an array to a function (by passing a pointer instead, see question 6.4 et al.). However, C has nothing truly equivalent to formal pass by reference or C++ reference parameters. (On the other hand, function-like preprocessor macros can provide a form of &quot;pass by name&quot;.) </code></pre> [2] <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dereference_operator" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dereference_operator</a>
评论 #14226644 未加载
评论 #14227548 未加载
评论 #14226919 未加载
评论 #14226596 未加载
评论 #14227487 未加载
评论 #14228379 未加载
pokstadabout 8 years ago
&quot;Maps and channels are not references.&quot;<p>But then refer to the Go team&#x27;s article on maps:<p><pre><code> Map types are reference types, like pointers or slices, and so the value of m above is nil; it doesn&#x27;t point to an initialized map. A nil map behaves like an empty map when reading, but attempts to write to a nil map will cause a runtime panic; don&#x27;t do that. To initialize a map, use the built in make function: m = make(map[string]int) The make function allocates and initializes a hash map data structure and returns a map value that points to it. The specifics of that data structure are an implementation detail of the runtime and are not specified by the language itself. In this article we will focus on the use of maps, not their implementation. </code></pre> Saying maps are not passed by reference is a bit deceiving. The map&#x27;s <i>pointer</i> location is not passed by reference.<p>Source: <a href="https:&#x2F;&#x2F;blog.golang.org&#x2F;go-maps-in-action" rel="nofollow">https:&#x2F;&#x2F;blog.golang.org&#x2F;go-maps-in-action</a>
评论 #14227556 未加载
kstenerudabout 8 years ago
It&#x27;s a question of semantics and the poorly chosen word &quot;reference&quot;.<p>The roots come from C, where pretty much every book on the subject talked about the difference between passing a huge, expensive value to a function vs passing a cheap pointer &quot;reference&quot; to it.<p>And while the semantic purists will scream and holler, the fact remains that, colloquially, a pointer is a reference to something, not the something itself. And so this annoying debate rears its ugly head a few times a year and makes it into HN or Slashdot or whatever.
评论 #14226718 未加载
pebersabout 8 years ago
Minor nit...<p>&gt; It is not possible to create a Go program where two variables share the same storage location in memory.<p>It is possible to do so, because the empty struct occupies no space. For example:<p><pre><code> s := []struct{}{ struct{}{}, struct{}{}, } fmt.Printf(&quot;%p %p\n&quot;, &amp;s[0], &amp;s[1]) &gt; 0x176f44 0x176f44 </code></pre> But that&#x27;s kind of a fringe case, and I suppose one might argue that the two variables occupy no space so in a sense they don&#x27;t share that space. Either way it doesn&#x27;t detract from the original point of the post :)
kstenerudabout 8 years ago
Often, I&#x27;ll deliberately give the naive &quot;pointers are references&quot; answer in a job interview, just to gauge the interviewer&#x27;s response.<p>It&#x27;s actually a good proxy to determining company culture. If he starts to patiently explain the difference, I&#x27;ll stop him and talk about the practical implications of the concept, and we&#x27;ll have a good laugh.<p>If he gets annoyed or stiffens and things become tense, I&#x27;ll have a good proxy for what to expect should I make the mistake of working there.
评论 #14226671 未加载
brianolsonabout 8 years ago
By this obtuse definition of &#x27;pass by reference&#x27;, Nothing with a C-like function call stack will &#x27;pass by reference&#x27;. Programming languages that approximate &#x27;pass by reference&#x27; will actually pass a pointer to the called function that points to a value in the callee&#x27;s stack frame. The pointer in the called function is a local variable, so changing the value of that has no effect in the callee&#x27;s scope. Changing the contents of the thing pointed to is the only _meaningful_ &#x27;pass by reference&#x27;, and practically most languages have that. (including Go)
elibenabout 8 years ago
Interestingly, the term &quot;reference type&quot; has been removed from the Go spec in 2013: <a href="https:&#x2F;&#x2F;github.com&#x2F;golang&#x2F;go&#x2F;commit&#x2F;b34f0551387fcf043d65cd7d96a0214956578f94" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;golang&#x2F;go&#x2F;commit&#x2F;b34f0551387fcf043d65cd7d...</a><p>Yet some semi-official sources (like The Go Programming Language book) <i>do</i> refer to channels as &quot;reference types&quot;.<p>TBH, I find cheney&#x27;s post not fully useful without explaining what <i>does</i> happen behind the scenes in maps so that passing them by value doesn&#x27;t incur large copies.
评论 #14226424 未加载
moominabout 8 years ago
C# has a name for Go&#x27;s object semantics: Marshal By Reference. This means that when an object features in a call, the GC pointer aka reference is passed (by value) rather than the object value itself. This reference is fundamentally different from the reference concept in C++. So the term reference is semantically overloaded and means different things in different programming languages. However, the phrase &quot;pass by reference&quot; is language independent and the author is correct, it doesn&#x27;t have those semantics.
Myrmornisabout 8 years ago
When teaching, rather than using a special name like &quot;pointer&quot;, wouldn&#x27;t it be better to simply explain that it&#x27;s a variable that holds a memory address? Once a student (e.g. who only knows a high-level language) understands that they now have to think about memory explicitly, then the behavior of such a variable will become obvious. AFAIU there are only two special features of pointers: the dereference operation and the additive arithmetic which increments in strides according to their type.
YZFabout 8 years ago
C++:<p><pre><code> void f(map&lt;int, int&gt; m) { m[0] = 0; } int main() { map&lt;int, int&gt; t; t[0] = 1; f(t); cout &lt;&lt; t[0] &lt;&lt; endl; return 0; } </code></pre> prints 1.<p>Go:<p><pre><code> func f(m map[int]int) { m[0] = 0 } func main(){ var t = make(map[int]int) t[0] = 1 f(t) fmt.Println(t[0]) } </code></pre> Prints 0.<p>So in C++ maps are passed by value. In Go they are passed by, hmm, &quot;not value&quot;.<p>Go could have made maps similar to C++ maps and then people could use a pointer to a map when they wanted that. As it stands maps are &quot;different&quot; which is not a big deal once you&#x27;re used to it but still makes things a little weird if you&#x27;re coming from C++.
Animatsabout 8 years ago
Go lacks the C++ reference operator. You can&#x27;t write:<p><pre><code> func fn(m &amp;map[int]int) { m = make(map[int]int) } ... fn(m) </code></pre> You have to write:<p><pre><code> func fn(m *map[int]int) { *m = make(map[int]int) } ... fn(&amp;m) </code></pre> It&#x27;s very C. The caller is forced to use different syntax to pass something as a pointer&#x2F;reference. In C++ and Rust, you can&#x27;t see from the call whether you&#x27;re passing a pointer or a reference.
评论 #14228213 未加载
zackmorrisabout 8 years ago
However, Go has pointers (just not pointer arithmetic):<p><a href="https:&#x2F;&#x2F;tour.golang.org&#x2F;moretypes&#x2F;1" rel="nofollow">https:&#x2F;&#x2F;tour.golang.org&#x2F;moretypes&#x2F;1</a><p>Does anyone know of an imperative language doesn&#x27;t have references, but also doesn&#x27;t have pointers? Perhaps using something like copy-on-write to pass variables to functions.
评论 #14233458 未加载
maxpblumabout 8 years ago
I haven&#x27;t used Go before; is there a common conception that you can pass by reference in Go?
评论 #14226576 未加载
评论 #14226497 未加载
评论 #14226488 未加载
htnsabout 8 years ago
Doesn&#x27;t the post stumble over right in the second section? &quot;It is not possible to create a Go program where two variables share the same storage location in memory&quot;. So what? The C example didn&#x27;t show that either.
评论 #14226763 未加载