TIL: You can use 'range' without an assignment

polaris · · 437 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;ve been using Go for sometime now, and I just knew about this while reading <a href="http://www.gopl.io" rel="nofollow">The Go Programming Language</a> book.</p> <pre><code>func main() { s := []string{&#34;one&#34;, &#34;two&#34;, &#34;three&#34;} for range s { fmt.Println(&#34;hello&#34;) } } </code></pre> <p><a href="http://play.golang.org/p/yCe8U3AvPW" rel="nofollow">playground</a></p> <p>to achieve the same behavior, I would&#39;ve used the following and <code>gofmt</code> doesn&#39;t seem to care.</p> <pre><code>func main() { s := []string{&#34;one&#34;, &#34;two&#34;, &#34;three&#34;} for _ = range s { fmt.Println(&#34;hello&#34;) } } </code></pre> <p><a href="http://play.golang.org/p/jRL9KqenyS" rel="nofollow">playground</a></p> <p>also I don&#39;t see this mentioned anywhere in the <a href="https://golang.org/doc/effective_go.html" rel="nofollow">Effective Go</a></p> <hr/>**评论:**<br/><br/>SSoreil: <pre><p>This was an addition to the language in Go 1.4 or Go 1.5. Probably the reason why checkers do not yet pick it up.</p></pre>dominikh: <pre><p><a href="https://github.com/golang/lint/pull/196" rel="nofollow">https://github.com/golang/lint/pull/196</a></p></pre>Sphax: <pre><p>gofmt -s fixes the form with _</p></pre>superjew: <pre><p>Why would you want to range over something and not use it?</p></pre>KenjiTakahashi: <pre><p>Remember that for is the only loop and that you can range over different things (e.g. channels). For example, this will run some code every second to infinity:</p> <pre><code>for range time.Tick(time.Second) { doStuffEverySecond() } </code></pre></pre>randfur: <pre><p>Probably to build up another data structure with the same length.</p></pre>: <pre><p>[deleted]</p></pre>randfur: <pre><p>That&#39;s a syntax error.</p></pre>carrier_pigeon: <pre><p>s := []string{&#34;one&#34;,&#34;two&#34;}</p> <p>i := len(s)</p> <p>ss:=make([]string,i)</p></pre>weberc2: <pre><p>The time.Ticker uses a channel that yields a value once per period. Often you don&#39;t care about the value, but only want to block until the value is yielded.</p></pre>earthboundkid: <pre><p>It&#39;s usually only useful for channels where the channel value is only informative as a sync event.</p></pre>uzimonkey: <pre><p>I think it would be easier to just use a <a href="http://play.golang.org/p/XdxlSULPgb" rel="nofollow">more traditional for loop</a>. While it probably doesn&#39;t matter for such a small array, I&#39;m not sure if the compiler would optimize away the actual array accesses and I&#39;d rather not rely on a trick. It&#39;s also more clear, where I&#39;d see the &#34;for range s&#34; and think &#34;for range what? I&#39;m iterating over something and not using it? Well, I suppose that&#39;ll just execute len(s) times then,&#34; but I know what the other for loop does immediately.</p></pre>LemurFromTheId: <pre><p>&#34;Traditional&#34; for loop is always prone to typos, and if you&#39;re not actually accessing the slice, you might not even get buffer overruns that would alert you to the problem - or worse: you might get them <em>elsewhere</em>. </p> <p><strong>for range s { }</strong> is perfectly readable and obvious in intent to anyone who spends non-zero time working with Go: it executes <strong>{ }</strong> once for every element in <strong>s</strong>. It&#39;s also concise and it doesn&#39;t introduce unnecessary variables.</p></pre>dchapes: <pre><blockquote> <p>would optimize away the actual array accesses</p> </blockquote> <p>There is no &#34;array access&#34; to &#34;optimize away&#34;. For arrays <code>len(array)</code> is a compile time constant. For slices <code>len(slice)</code> is just a simple variable access, no computation required (unlike, for example, C&#39;s <code>strlen</code> or the length of a linked list). In either case if you have <code>for i := range foo</code> or <code>for range foo</code> (or even <code>for i, _ := range foo</code>) then elements of the array/slice are not accessed at all as part of the <code>for</code> statement.</p> <p>The only case where those <code>for</code> loops wouldn&#39;t be simple counting loops is if <code>foo</code> was a string. <code>for i := range str</code> or <code>for range str</code> need to look through the bytes of the string looking for multibyte runes.</p></pre>

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

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