Short vs. long variable declarations

blov · · 493 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Which do you default to? I see a lot of code using short decls in most cases, and only using long decls with no initialization where the zero value is needed.</p> <p>It seems to me that long decls should be the default declaration used because short delcs are context-sensitive. That is, you have no idea what this is doing:</p> <pre><code>x, y := z() </code></pre> <p>It might be declaring x and y, or just x, or just y. This leads to common copy/paste and variable shadowing errors. Long declarations don&#39;t have those problems. As a bonus, the long declaration syntax matches those for consts and types:</p> <pre><code>const c = ... type t ... var x = ... </code></pre> <p>So I use long declarations unless I need to declare a new variable in combination with assigning to an existing variable, like reusing an err variable:</p> <pre><code>var w, err = x() y, err := z() </code></pre> <p>The short declaration draws attention to the fact that something clever is going on.</p> <p>What do you think, and what do you do yourself?</p> <hr/>**评论:**<br/><br/>metamatic: <pre><p>I wish we didn&#39;t have to have both of them.</p></pre>dilap: <pre><p>I tend to use the short form because it&#39;s shorter, and it avoids the unnecessary verbiage of &#34;var&#34; in my head (as dumb as it is, I still tend to mentally vocalize all the words I see).</p></pre>gohacker: <pre><p>I prefer <code>var xxx someStruct</code> rather than <code>xxx := someStruct{}</code>, when I&#39;m going to unmarshal some value into <code>xxx</code> . Just a matter of taste.</p></pre>tscs37: <pre><p><del>You&#39;re gonna get a nil error then unless you initialize the variable.</del></p> <p><del>I prefer <code>var xxx = someStruct{}</code> for that.</del></p> <p>As pointed out this is not a problem on a direct struct I actually use <code>var xxx = &amp;someStruct{}</code>, got that confused.</p></pre>peterbourgon: <pre><p>Your statement is entirely equivalent to the one in the parent. What nil error are you referring to? </p></pre>tscs37: <pre><p>Sorry I was refering to a pointer struct, got that a bit confused.</p> <p>I&#39;ll fix that in a sec; I usually don&#39;t use <code>var xxx someStruct</code> and rather <code>xxx *someStruct</code> so I can pass it through validation/authentication after unmarshalling it without having to get the pointer to it all the time.</p></pre>Zy14rk: <pre><p>I&#39;m stuck in the Modula2 school of variable declarations, so I do them explicitly using the var keyword and type just as soon as a func is declared. And the package globals at the very top. All huddled together to keep nice, snug and social with eachother. They are also given proper names. Same with variables declared in a funcs args and return list.</p> <p>Temporary variables however are strewn all over the place using the := method with implicit type and seldom consist of names longer than one char.</p> <p>Makes it easily readable in my opinion. No need to scour a func to the very end to get an idea of what it does. the first few lines will do. Yup, it takes this data, uses internally these representations, and outputs that. Good. Next.</p></pre>dmikalova: <pre><p>Use the short declaration as much as possible.</p> <p>What shadowing errors are you getting? The only time I&#39;ve heard of that being an issue in Go are loops unintentionally using variables outside of the loop. I feel like you may be using very long functions that should be broken down into smaller ones - a function shouldn&#39;t need two x&#39;s that have different meanings.</p></pre>indil7: <pre><p>Why use short as much as possible?</p> <p>Even if the shadowing doesn&#39;t bother you, what about the other points?</p> <p>Nope, no long funcs. Shadowing example:</p> <pre><code>id := ... if ... { id, err := ... // id shadowed, value lost to outer scope } fmt.Println(id) </code></pre></pre>ynori7: <pre><p>In this case you&#39;d need to define err outside of that scope too and use a normal &#39;=&#39; instead of &#39;:=&#39;.</p> <p>In my functions, &#34;err&#34; is often reused so I sometimes declare that explicitly at the top of the function like:</p> <pre><code>var err error </code></pre></pre>indil7: <pre><p>Right. My point is that unintentional variable shadowing sometimes happens by mistake, so using long decls avoids that category of bugs entirely, right?</p></pre>dmikalova: <pre><p>Yeah that&#39;s the one shadowing case I&#39;ve heard of being common. There&#39;s nothing really funny going on though - the compiler is just doing exactly what you&#39;re telling it to and in many cases the shadowing is an intentional effect.</p> <p>The thing is using long decls here doesn&#39;t avoid the bug - not using a long decl here is the bug. You may find it necessary to avoid the bug completely wherever possible, but I think it&#39;d be easier to just add <code>go vet --shadow</code> into your toolchain - for example with gometalinter.</p> <p>Using long decls everywhere without knowing what you&#39;re doing also leads to the reverse issue - variables not escaping the loop. Why not just learn and pay attention?</p></pre>indil7: <pre><p>The compiler is always doing what you tell it to, so I don&#39;t understand your point.</p> <p>The post only addresses unintentional shadowing; of course shadowing is sometimes intended.</p> <p>If there&#39;s a bug one way and not another way, then the other way avoids the bug. Call it &#34;error&#34; if you want to, as in copy/paste errors; the programmer error still results in a bug.</p> <p>Isn&#39;t vetting shadowed variables pointless if, as you pointed out, sometimes that&#39;s what you want to do? Why not write syntax that most clearly expresses your intent and avoid the issue altogether?</p> <p>Not sure I understand what you mean about variables (I assume you mean assignments) not escaping loops; it doesn&#39;t escape using either decl because it&#39;s declared in the loop.</p> <p>I liked your points about how I don&#39;t know what I&#39;m doing, and how I&#39;m not learning, and how I&#39;m not paying attention — thanks. I guess using Go professionally for at least 2 years doesn&#39;t amount to much. I guess I&#39;m a real jackass.</p> <p>Doing this isn&#39;t out of ignorance or laziness; it&#39;s out of pragmatism, for the reasons I&#39;ve already explained.</p></pre>

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

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