You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

518 lines
30 KiB
HTML

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="zh-cn" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="遍历 - for-range语法 # for-range语法可以用来遍历数组、指向数组的指针切片、字符串、映射和通道。
遍历数组 # 当遍历一个数组a时候循环范围会从0到len(a) -1
func main() { var a [3]int for i, v := range a { fmt.Println(i, v) } for i, v := range &amp;a { fmt.Println(i, v) } } 遍历切片 # 当遍历一个切片s时候循环范围会从0到len(s) -1若切片是nil则迭代次数是0次
func main() { a := make([]int, 3) for i, v := range a { fmt.Println(i, v) } a = nil for i, v := range a { fmt.Println(i, v) } } for-range切片时候可以边遍历边append吗 # 当遍历切片时候可以边遍历边append操作这并不会造成死循环。因为遍历之前已经确定了循环范围遍历操作相当如下伪代码">
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#ffffff">
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#343a40">
<meta name="color-scheme" content="light dark"><meta property="og:title" content="for-range语法" />
<meta property="og:description" content="遍历 - for-range语法 # for-range语法可以用来遍历数组、指向数组的指针切片、字符串、映射和通道。
遍历数组 # 当遍历一个数组a时候循环范围会从0到len(a) -1
func main() { var a [3]int for i, v := range a { fmt.Println(i, v) } for i, v := range &amp;a { fmt.Println(i, v) } } 遍历切片 # 当遍历一个切片s时候循环范围会从0到len(s) -1若切片是nil则迭代次数是0次
func main() { a := make([]int, 3) for i, v := range a { fmt.Println(i, v) } a = nil for i, v := range a { fmt.Println(i, v) } } for-range切片时候可以边遍历边append吗 # 当遍历切片时候可以边遍历边append操作这并不会造成死循环。因为遍历之前已经确定了循环范围遍历操作相当如下伪代码" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://go.cyub.vip/feature/for-range/" /><meta property="article:section" content="feature" />
<title>for-range语法 | 深入Go语言之旅</title>
<link rel="manifest" href="/manifest.json">
<link rel="icon" href="/favicon.png" >
<link rel="stylesheet" href="/book.min.f06572240ce28e67eb332ac5cf5d59a696c47ad4c6f700d5842c5ed93dd8ec77.css" integrity="sha256-8GVyJAzijmfrMyrFz11ZppbEetTG9wDVhCxe2T3Y7Hc=" crossorigin="anonymous">
<script defer src="/flexsearch.min.js"></script>
<script defer src="/en.search.min.17ed8785d618483565ce5458241250de0bb24d7b931b8b71446036ef43affd37.js" integrity="sha256-F&#43;2HhdYYSDVlzlRYJBJQ3guyTXuTG4txRGA270Ov/Tc=" crossorigin="anonymous"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-BQ229RRTTX"></script>
<script>
var doNotTrack = false;
if (!doNotTrack) {
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-BQ229RRTTX', { 'anonymize_ip': false });
}
</script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir="ltr">
<input type="checkbox" class="hidden toggle" id="menu-control" />
<input type="checkbox" class="hidden toggle" id="toc-control" />
<main class="container flex">
<aside class="book-menu">
<div class="book-menu-content">
<nav>
<h2 class="book-brand">
<a class="flex align-center" href="/"><img src="https://static.cyub.vip/images/202310/golang-480.png" alt="Logo" /><span>深入Go语言之旅</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<a href="https://www.cyub.vip/" target="_blank" rel="noopener">
个人博客
</a>
</li>
<li>
<a href="https://github.com/cyub" target="_blank" rel="noopener">
Github主页
</a>
</li>
<li>
<a href="https://www.topgoer.cn/?ref=go.cyub.vip" target="_blank" rel="noopener">
地鼠文档
</a>
</li>
</ul>
<ul>
<li>
<p><strong>
<a href="/">深入Go语言之旅</a></strong></p>
</li>
<li>
<p><strong>准备篇</strong></p>
<ul>
<li>
<a href="/compiler/">编译流程</a></li>
<li>
<a href="/analysis-tools/">分析工具</a>
<ul>
<li>
<a href="/analysis-tools/gdb/">GDB</a></li>
<li>
<a href="/analysis-tools/dlv/">Delve</a></li>
<li>
<a href="/analysis-tools/go-buildin-tools/">Go 内置工具</a></li>
</ul>
</li>
<li>
<a href="/go-assembly/">Go汇编</a></li>
</ul>
</li>
<li>
<p><strong>基础篇</strong></p>
<ul>
<li>
<a href="/type/">数据类型与数据结构</a>
<ul>
<li>
<a href="/type/string/">字符串</a></li>
<li>
<a href="/type/array/">数组</a></li>
<li>
<a href="/type/slice/">切片</a></li>
<li>
<a href="/type/nil/">nil</a></li>
<li>
<a href="/type/empty_struct/">空结构体</a></li>
<li>
<a href="/type/pointer/">指针</a></li>
<li>
<a href="/type/map/">映射</a></li>
</ul>
</li>
<li>
<a href="/function/">函数</a>
<ul>
<li>
<a href="/function/first-class/">一等公民</a></li>
<li>
<a href="/function/call-stack/">函数调用栈</a></li>
<li>
<a href="/function/pass-by-value/">值传递</a></li>
<li>
<a href="/function/closure/">闭包</a></li>
<li>
<a href="/function/method/">方法</a></li>
</ul>
</li>
<li>
<a href="/feature/">语言特性</a>
<ul>
<li>
<a href="/feature/comma-ok/">逗号ok模式</a></li>
<li>
<a href="/feature/for-range/"class=active>遍历 - for-range语法</a></li>
<li>
<a href="/feature/defer/">延迟执行 - defer语法</a></li>
<li>
<a href="/feature/select/">通道选择器 - select语法</a></li>
<li>
<a href="/feature/panic-recover/">恐慌与恢复 - panic/recover</a></li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>运行时篇</strong></p>
<ul>
<li>
<a href="/concurrency/">并发编程</a>
<ul>
<li>
<a href="/concurrency/memory-model/">内存模型</a></li>
<li>
<a href="/concurrency/context/">上下文 - context</a></li>
<li>
<a href="/concurrency/channel/">通道 - channel</a></li>
<li>
<a href="/concurrency/atomic/">原子操作 - atomic</a></li>
<li>
<a href="/concurrency/sync-map/">并发Map - sync.Map</a></li>
<li>
<a href="/concurrency/sync-waitgroup/">等待组 - sync.WaitGroup</a></li>
<li>
<a href="/concurrency/sync-once/">一次性操作 - sync.Once</a></li>
<li>
<a href="/concurrency/sync-pool/">缓冲池 - sync.Pool</a></li>
<li>
<a href="/concurrency/sync-cond/">条件变量 - sync.Cond</a></li>
<li>
<a href="/concurrency/sync-mutex/">互斥锁 - sync.Mutex</a></li>
<li>
<a href="/concurrency/sync-rwmutex/">读写锁 - sync.RWMutex</a></li>
</ul>
</li>
<li>
<a href="/gmp/">G-M-P调度机制</a>
<ul>
<li>
<a href="/gmp/gmp-model/">调度机制概述</a></li>
<li>
<a href="/gmp/scheduler/">调度器</a></li>
</ul>
</li>
<li>
<a href="/memory/">内存管理</a>
<ul>
<li>
<a href="/memory/allocator/">内存分配器</a></li>
<li>
<a href="/memory/gc/">GC</a></li>
</ul>
</li>
<li>
<a href="/type-system/">类型系统</a>
<ul>
<li>
<a href="/type-system/type/">类型系统</a></li>
<li>
<a href="/type-system/interface/">接口</a></li>
<li>
<a href="/type-system/reflect/">反射</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
<script>(function(){var e=document.querySelector("aside .book-menu-content");addEventListener("beforeunload",function(){localStorage.setItem("menu.scrollTop",e.scrollTop)}),e.scrollTop=localStorage.getItem("menu.scrollTop")})()</script>
</div>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>for-range语法</strong>
<label for="toc-control">
</label>
</div>
</header>
<article class="markdown"><h1 id="遍历---for-range语法">
遍历 - for-range语法
<a class="anchor" href="#%e9%81%8d%e5%8e%86---for-range%e8%af%ad%e6%b3%95">#</a>
</h1>
<p>for-range语法可以用来遍历数组、指向数组的指针切片、字符串、映射和通道。</p>
<h2 id="遍历数组">
遍历数组
<a class="anchor" href="#%e9%81%8d%e5%8e%86%e6%95%b0%e7%bb%84">#</a>
</h2>
<p>当遍历一个数组a时候循环范围会从0到len(a) -1</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">a</span> [<span style="color:#ae81ff">3</span>]<span style="color:#66d9ef">int</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">a</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">a</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="遍历切片">
遍历切片
<a class="anchor" href="#%e9%81%8d%e5%8e%86%e5%88%87%e7%89%87">#</a>
</h2>
<p>当遍历一个切片s时候循环范围会从0到len(s) -1若切片是nil则迭代次数是0次</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">a</span> <span style="color:#f92672">:=</span> make([]<span style="color:#66d9ef">int</span>, <span style="color:#ae81ff">3</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">a</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">a</span> = <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">a</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="for-range切片时候可以边遍历边append吗">
for-range切片时候可以边遍历边append吗
<a class="anchor" href="#for-range%e5%88%87%e7%89%87%e6%97%b6%e5%80%99%e5%8f%af%e4%bb%a5%e8%be%b9%e9%81%8d%e5%8e%86%e8%be%b9append%e5%90%97">#</a>
</h3>
<p>当遍历切片时候可以边遍历边append操作这并不会造成死循环。因为遍历之前已经确定了循环范围遍历操作相当如下伪代码</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#a6e22e">len_temp</span> <span style="color:#f92672">:=</span> len(<span style="color:#66d9ef">range</span>) <span style="color:#75715e">// 循环上界
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">range_temp</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> <span style="color:#a6e22e">index_temp</span> = <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">index_temp</span> &lt; <span style="color:#a6e22e">len_temp</span>; <span style="color:#a6e22e">index_temp</span><span style="color:#f92672">++</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">value_temp</span> = <span style="color:#a6e22e">range_temp</span>[<span style="color:#a6e22e">index_temp</span>]
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">index</span> = <span style="color:#a6e22e">index_temp</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">value</span> = <span style="color:#a6e22e">value_temp</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">original</span> <span style="color:#a6e22e">body</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="for-range切片时候返回的是值拷贝">
for-range切片时候返回的是值拷贝
<a class="anchor" href="#for-range%e5%88%87%e7%89%87%e6%97%b6%e5%80%99%e8%bf%94%e5%9b%9e%e7%9a%84%e6%98%af%e5%80%bc%e6%8b%b7%e8%b4%9d">#</a>
</h3>
<p>无论遍历数组还是切片,返回都是数组或切片中的值拷贝:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">users</span> <span style="color:#f92672">:=</span> []<span style="color:#a6e22e">User</span>{
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span>: <span style="color:#e6db74">&#34;a1&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Age</span>: <span style="color:#ae81ff">100</span>,
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span>: <span style="color:#e6db74">&#34;a2&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Age</span>: <span style="color:#ae81ff">101</span>,
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span>: <span style="color:#e6db74">&#34;a2&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Age</span>: <span style="color:#ae81ff">102</span>,
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;before: &#34;</span>, <span style="color:#a6e22e">users</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">v</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">users</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">v</span>.<span style="color:#a6e22e">Age</span> = <span style="color:#a6e22e">v</span>.<span style="color:#a6e22e">Age</span> <span style="color:#f92672">+</span> <span style="color:#ae81ff">10</span> <span style="color:#75715e">// 想给users中所有用户年龄增加10岁
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> }
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;after: &#34;</span>, <span style="color:#a6e22e">users</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>执行上面代码,输入以下内容:</p>
<pre tabindex="0"><code>before: [{a1 100} {a2 101} {a2 102}]
after: [{a1 100} {a2 101} {a2 102}]
</code></pre><p>解决办法可以通过索引访问原切片或数组:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">users</span> <span style="color:#f92672">:=</span> []<span style="color:#a6e22e">User</span>{
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span>: <span style="color:#e6db74">&#34;a1&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Age</span>: <span style="color:#ae81ff">100</span>,
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span>: <span style="color:#e6db74">&#34;a2&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Age</span>: <span style="color:#ae81ff">101</span>,
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Name</span>: <span style="color:#e6db74">&#34;a2&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Age</span>: <span style="color:#ae81ff">102</span>,
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;before: &#34;</span>, <span style="color:#a6e22e">users</span>)
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">users</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">users</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">Age</span> = <span style="color:#a6e22e">users</span>[<span style="color:#a6e22e">i</span>].<span style="color:#a6e22e">Age</span> <span style="color:#f92672">+</span> <span style="color:#ae81ff">10</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;after: &#34;</span>, <span style="color:#a6e22e">users</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="遍历字符串">
遍历字符串
<a class="anchor" href="#%e9%81%8d%e5%8e%86%e5%ad%97%e7%ac%a6%e4%b8%b2">#</a>
</h2>
<p>当遍历字符串时候返回的是rune类型rune类型是int32类型的别名一个rune就是一个码点(code point)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#75715e">// rune is an alias for int32 and is equivalent to int32 in all ways. It is
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">// used, by convention, to distinguish character values from integer values.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">type</span> <span style="color:#66d9ef">rune</span> = <span style="color:#66d9ef">int32</span>
</span></span></code></pre></div><p>由于遍历字符串时候返回的是码点所以索引并不总是依次增加1的</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">str</span> = <span style="color:#e6db74">&#34;hello你好&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">buf</span> [<span style="color:#ae81ff">100</span>]<span style="color:#66d9ef">byte</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">str</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">vl</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">utf8</span>.<span style="color:#a6e22e">RuneLen</span>(<span style="color:#a6e22e">v</span>)
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">si</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">vl</span>
</span></span><span style="display:flex;"><span> copy(<span style="color:#a6e22e">buf</span>[:], <span style="color:#a6e22e">str</span>[<span style="color:#a6e22e">i</span>:<span style="color:#a6e22e">si</span>])
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;索引%2d: %q\t 码点: %#6x\t 码点转换成字节: %#v\n&#34;</span>, <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span>, <span style="color:#a6e22e">v</span>, <span style="color:#a6e22e">buf</span>[:<span style="color:#a6e22e">vl</span>])
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>执行上面代码将输出以下内容:</p>
<pre tabindex="0"><code>索引 0: &#39;h&#39; 码点: 0x68 码点转换成字节: []byte{0x68}
索引 1: &#39;e&#39; 码点: 0x65 码点转换成字节: []byte{0x65}
索引 2: &#39;l&#39; 码点: 0x6c 码点转换成字节: []byte{0x6c}
索引 3: &#39;l&#39; 码点: 0x6c 码点转换成字节: []byte{0x6c}
索引 4: &#39;o&#39; 码点: 0x6f 码点转换成字节: []byte{0x6f}
索引 5: &#39;&#39; 码点: 0xff0c 码点转换成字节: []byte{0xef, 0xbc, 0x8c}
索引 8: &#39;&#39; 码点: 0x4f60 码点转换成字节: []byte{0xe4, 0xbd, 0xa0}
索引11: &#39;&#39; 码点: 0x597d 码点转换成字节: []byte{0xe5, 0xa5, 0xbd}
</code></pre><h2 id="遍历映射">
遍历映射
<a class="anchor" href="#%e9%81%8d%e5%8e%86%e6%98%a0%e5%b0%84">#</a>
</h2>
<p>当遍历切片时候Go语言是不会保证遍历顺序的为了明确强调这一点Go语言在实现的时候故意随机地选择一个桶开始遍历。当映射通道为nil时候遍历次数为0次。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">m</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">map</span>[<span style="color:#66d9ef">int</span>]<span style="color:#66d9ef">int</span>{
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">1</span>: <span style="color:#ae81ff">10</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">2</span>: <span style="color:#ae81ff">20</span>,
</span></span><span style="display:flex;"><span> <span style="color:#ae81ff">3</span>: <span style="color:#ae81ff">30</span>,
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">m</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">m</span> = <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">m</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">v</span>)
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="for-range映射时候可以边遍历边新增或删除吗">
for-range映射时候可以边遍历边新增或删除吗
<a class="anchor" href="#for-range%e6%98%a0%e5%b0%84%e6%97%b6%e5%80%99%e5%8f%af%e4%bb%a5%e8%be%b9%e9%81%8d%e5%8e%86%e8%be%b9%e6%96%b0%e5%a2%9e%e6%88%96%e5%88%a0%e9%99%a4%e5%90%97">#</a>
</h3>
<p>若在一个Goroutine里面边遍历边新增、删除理论上是可以的不会触发写检测的新增的key-value可能会被访问到也可能不会。</p>
<p>若多个Goroutine中进行遍历、新增、删除操作的话是不可以的是可能触发写检测的然后直接panic。</p>
<h2 id="遍历通道">
遍历通道
<a class="anchor" href="#%e9%81%8d%e5%8e%86%e9%80%9a%e9%81%93">#</a>
</h2>
<p>当遍历通道时直到通道关闭才会终止若通道是nil则会永远阻塞。遍历通道源码分析请见
<a href="/concurrency/channel/#id4">从通道中读取数据</a></p>
<h2 id="进一步阅读">
进一步阅读
<a class="anchor" href="#%e8%bf%9b%e4%b8%80%e6%ad%a5%e9%98%85%e8%af%bb">#</a>
</h2>
<ul>
<li>
<a href="https://garbagecollected.org/2017/02/22/go-range-loop-internals/">Go Range Loop Internals</a></li>
<li>
<a href="https://golang.org/ref/spec#For_statements">For statements</a></li>
</ul>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
<script>(function(){function e(e){const t=window.getSelection(),n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)}document.querySelectorAll("pre code").forEach(t=>{t.addEventListener("click",function(){if(window.getSelection().toString())return;e(t.parentElement),navigator.clipboard&&navigator.clipboard.writeText(t.parentElement.textContent)})})})()</script>
</footer>
<div class="book-comments">
<script src="https://giscus.app/client.js" data-repo="cyub/go-1.14.13"
data-repo-id="MDEwOlJlcG9zaXRvcnkzMzc2ODUyMzQ=" data-category="Announcements"
data-category-id="DIC_kwDOFCCq8s4CZ3BC"
data-mapping="pathname" data-strict="0" data-emit-metadata="0"
data-input-position="bottom" data-reactions-enabled="0"
data-lang="zh-CN" data-theme="preferred_color_scheme" crossorigin="anonymous" async>
</script>
<noscript>Please enable JavaScript to view the comments powered by giscus.</noscript>
</div>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
</main>
</body>
</html>