|
|
<!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 &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 &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+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">&</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> < <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">"a1"</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">"a2"</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">"a2"</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">"before: "</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">"after: "</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">"a1"</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">"a2"</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">"a2"</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">"before: "</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">"after: "</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">"hello,你好"</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">"索引%2d: %q,\t 码点: %#6x,\t 码点转换成字节: %#v\n"</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: 'h', 码点: 0x68, 码点转换成字节: []byte{0x68}
|
|
|
索引 1: 'e', 码点: 0x65, 码点转换成字节: []byte{0x65}
|
|
|
索引 2: 'l', 码点: 0x6c, 码点转换成字节: []byte{0x6c}
|
|
|
索引 3: 'l', 码点: 0x6c, 码点转换成字节: []byte{0x6c}
|
|
|
索引 4: 'o', 码点: 0x6f, 码点转换成字节: []byte{0x6f}
|
|
|
索引 5: ',', 码点: 0xff0c, 码点转换成字节: []byte{0xef, 0xbc, 0x8c}
|
|
|
索引 8: '你', 码点: 0x4f60, 码点转换成字节: []byte{0xe4, 0xbd, 0xa0}
|
|
|
索引11: '好', 码点: 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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|