Go語言中的條件判斷和for循環(huán)舉例詳解
1、if 條件判斷
在 Go 語言中,if
條件判斷是一種基本的控制流結(jié)構(gòu),用于根據(jù)條件的真假來執(zhí)行不同的代碼塊。其語法簡潔明了,易于上手。
1、基礎(chǔ)語法
if
語句的基本語法格式如下:
if boolean_expression { // 當(dāng)布爾表達(dá)式為 true 時(shí),執(zhí)行這里的代碼 }
關(guān)鍵點(diǎn):
條件
boolean_expression
必須是一個(gè)結(jié)果為布爾值(true
或false
)的表達(dá)式。與許多其他語言不同,Go 語言的
if
條件不需要用括號()
包圍,但執(zhí)行體的花括號{}
是必需的。按照 Go 的編碼規(guī)范,左花括號
{
應(yīng)當(dāng)與if
關(guān)鍵字在同一行。
讓我們來看一個(gè)判斷年齡的簡單示例:
在上面的代碼中,因?yàn)?nbsp;age < 18
的結(jié)果為 true
,所以程序會打印“未成年”。如果將 age
的值改為 22
,則條件不成立,if
塊內(nèi)的代碼不會被執(zhí)行。
2、復(fù)合條件
在實(shí)際開發(fā)中,我們常常需要判斷多個(gè)條件。這時(shí)可以使用邏輯運(yùn)算符 &&
(與) 和 ||
(或) 來構(gòu)建復(fù)合條件。
例如,我們需要同時(shí)判斷年齡和國籍:
只有當(dāng) age < 18
并且 country == "中國"
這兩個(gè)條件都為 true
時(shí),判斷才會成立。如果其中任何一個(gè)條件為 false
,整個(gè)表達(dá)式的結(jié)果就是 false
。
當(dāng)條件邏輯變得復(fù)雜時(shí),可以使用括號 ()
來明確分組和優(yōu)先級,確保邏輯的正確性。
3、嵌套 if
if
語句內(nèi)部可以包含另一個(gè) if
語句,形成嵌套結(jié)構(gòu),以實(shí)現(xiàn)更復(fù)雜的邏輯判斷。
這個(gè)嵌套 if
的邏輯與前面使用 &&
的復(fù)合條件是等價(jià)的,但在某些場景下,嵌套結(jié)構(gòu)能讓代碼層次更分明。
4、if-else 與 else if
為了處理?xiàng)l件不成立時(shí)的情況,我們可以使用 else
。當(dāng) if
的條件為 false
時(shí),程序?qū)⒆詣訄?zhí)行 else
塊中的代碼。
如果需要處理多個(gè)互斥的條件,可以使用 else if
結(jié)構(gòu)。程序會從上到下依次判斷,一旦某個(gè) if
或 else if
的條件成立,就會執(zhí)行其對應(yīng)的代碼塊,并跳過所有剩余的 else if
和 else
。
5、最佳實(shí)踐:if-else if vs. 多個(gè) if
思考以下兩種寫法,它們在功能上似乎是等價(jià)的:
寫法一:使用 if-else if-else
(推薦)
寫法二:使用多個(gè)獨(dú)立的 if
為什么推薦寫法一?
邏輯清晰:
if-else if
結(jié)構(gòu)明確地表達(dá)了一系列互斥的條件,閱讀代碼時(shí)能立刻明白這些條件中只有一個(gè)會成立。性能更優(yōu):當(dāng)
age
為16
時(shí),寫法一在判斷age < 18
成立后,便不再執(zhí)行后續(xù)的else if
和else
判斷。而寫法二則會繼續(xù)執(zhí)行后續(xù)的兩個(gè)if
判斷,進(jìn)行了不必要的比較操作。雖然在簡單場景下性能差異微乎其微,但在復(fù)雜邏輯或循環(huán)中,這種差異可能會被放大。
因此,在處理一系列互斥條件時(shí),應(yīng)優(yōu)先使用 if-else if-else
結(jié)構(gòu)。
2、for循環(huán)基礎(chǔ)用法
Go 語言在循環(huán)結(jié)構(gòu)的設(shè)計(jì)上秉持了其一貫的簡潔風(fēng)格,僅提供了 for 這一種循環(huán)關(guān)鍵字。這與其他編程語言(如 C, Java, Python)同時(shí)提供 for
和 while
循環(huán)的做法不同。
Go 的設(shè)計(jì)者認(rèn)為,for
循環(huán)足夠靈活,可以完全覆蓋 while
循環(huán)的所有使用場景。通過省略 for
循環(huán)的某些部分,可以輕松模擬出 while
的行為。這種設(shè)計(jì)減少了語言的關(guān)鍵字?jǐn)?shù)量,使得語法更加統(tǒng)一。
1、for 循環(huán)的基礎(chǔ)語法
for
循環(huán)的標(biāo)準(zhǔn)形式包含三個(gè)部分,由分號 ;
分隔,分別對應(yīng):初始化語句、條件表達(dá)式和后置語句。
for initialization; condition; post { // 循環(huán)體代碼 }
初始化語句 (initialization):在循環(huán)開始前執(zhí)行,通常用于聲明和初始化一個(gè)局部循環(huán)變量。
條件表達(dá)式 (condition):在每次循環(huán)迭代開始前進(jìn)行求值。如果為
true
,則執(zhí)行循環(huán)體;如果為false
,則退出循環(huán)。后置語句 (post):在每次循環(huán)迭代結(jié)束后執(zhí)行,通常用于更新循環(huán)變量。
與 if
語句一樣,for
循環(huán)的條件部分不需要括號。
讓我們通過一個(gè)打印數(shù)字 0 到 2 的例子來了解其用法:
2、靈活的 for 循環(huán) (模擬 while)
for
循環(huán)的三個(gè)部分都不是必需的,可以根據(jù)需要省略,這使得 for
循環(huán)非常靈活,能夠輕松模擬 while
循環(huán)。
2.1 模擬 while (condition)
通過省略初始化語句和后置語句,只保留條件表達(dá)式,for
循環(huán)就等同于 while
循環(huán)。
這段代碼的執(zhí)行效果與前一個(gè)例子完全相同。
2.2 模擬無限循環(huán) while (true)
如果將三個(gè)部分全部省略,就構(gòu)成了一個(gè)無限循環(huán),等效于其他語言中的 while (true)
或 for(;;)
。這在需要持續(xù)運(yùn)行的服務(wù)或監(jiān)聽事件的場景中非常常見。
在無限循環(huán)中,通常需要一個(gè)明確的退出條件,可以使用 break
語句來跳出循環(huán)。例如,我們可以在循環(huán)體內(nèi)加入一個(gè) if
判斷:
這個(gè)例子最終也只會打印 0, 1, 2,然后程序正常結(jié)束。這種 for
結(jié)合 if-break
的模式是 Go 中實(shí)現(xiàn)條件循環(huán)的常用方式。
3、for 循環(huán)打印 九九乘法表
掌握了 for
循環(huán)的基礎(chǔ)之后,我們通過兩個(gè)經(jīng)典的編程練習(xí)來鞏固所學(xué)知識:計(jì)算 1 到 100 的累加和,以及打印九九乘法表。
1、計(jì)算 1 到 100 的和
這是一個(gè)非常基礎(chǔ)的循環(huán)應(yīng)用。我們的思路是:
在循環(huán)外部定義一個(gè)用于累加求和的變量
sum
。使用
for
循環(huán),讓循環(huán)變量i
從 1 遍歷到 100。在每次循環(huán)中,將當(dāng)前的循環(huán)變量
i
的值累加到sum
上。循環(huán)結(jié)束后,打印
sum
的值。
代碼解析:
sum := 0
:初始化sum
為 0。這個(gè)變量必須在循環(huán)外部定義,否則每次循環(huán)都會被重置。for i := 1; i <= 100; i++
:經(jīng)典的for
循環(huán)結(jié)構(gòu),i
的取值范圍是[1, 100]
。sum += i
:這是 Go 中的復(fù)合賦值操作符,是sum = sum + i
的簡寫形式,代碼更簡潔。
2、打印九九乘法表
打印九九乘法表需要使用嵌套循環(huán),一個(gè)外層循環(huán)控制行數(shù),一個(gè)內(nèi)層循環(huán)控制列數(shù)。
邏輯分析:
九九乘法表總共有 9 行。
第
i
行有i
個(gè)表達(dá)式。例如,第 2 行有兩個(gè)(2*1
,2*2
),第 5 行有五個(gè)。這表明內(nèi)層循環(huán)的次數(shù)是受外層循環(huán)的當(dāng)前變量控制的。
代碼解析:
外層循環(huán)
for i := 1; i <= 9; i++
:控制從第 1 行到第 9 行。內(nèi)層循環(huán)
for j := 1; j <= i; j++
:是關(guān)鍵所在。它控制每一行需要打印的表達(dá)式數(shù)量。當(dāng)外層循環(huán)i
為 3 時(shí),內(nèi)層循環(huán)j
會從 1 循環(huán)到 3,從而打印出三個(gè)表達(dá)式。fmt.Printf
:用于格式化輸出。%d
是數(shù)字的占位符,%-2d
表示輸出一個(gè)左對齊且至少占 2 個(gè)字符寬度的數(shù)字,這能讓乘法表看起來更整齊。fmt.Println()
:在內(nèi)層循環(huán)結(jié)束后,用于輸出一個(gè)換行符,以便開始新一行的打印。
4、for range 的循環(huán)用法
除了標(biāo)準(zhǔn)的三段式 for
循環(huán),Go 還提供了一種更強(qiáng)大、更便捷的 for range
結(jié)構(gòu),專門用于遍歷各種數(shù)據(jù)集合,類似其他語言中的 foreach
。for range
可以用于遍歷字符串、數(shù)組、切片、map 和 channel。
1、for range 的語法
其基本語法格式如下:
for key, value := range collection { // ... }
collection
:表示待遍歷的數(shù)據(jù)集合。key
,value
:每次循環(huán),for range
會從中collection
取出一對值,分別賦值給key
和value
。這對變量的含義取決于被遍歷的數(shù)據(jù)類型。:=
:這里必須使用短變量聲明,它會為每次循環(huán)迭代創(chuàng)建新的key
和value
變量。
2、遍歷字符串
當(dāng) for range
用于遍歷字符串時(shí):
key
是每個(gè)字符的起始字節(jié)索引 (index)。value
是該字符對應(yīng)的 Unicode 碼點(diǎn) (類型為rune
),而不是字符本身。
注意:value
得到的是原值的拷貝,在循環(huán)中修改 value
不會影響原始的 collection
。
3、for range 的靈活用法
3.1 忽略變量
如果你在循環(huán)中不需要 key
或 value
,可以使用匿名變量(下劃線 _
)來忽略它,以避免編譯器報(bào)“聲明但未使用的變量”錯(cuò)誤。
3.2 只接收一個(gè)返回值
如果 for range
只接收一個(gè)變量,那么該變量接收到的值是 key
(對于字符串、數(shù)組、切片來說就是索引)。
4、for range 與不同數(shù)據(jù)類型的行為
|數(shù)據(jù)類型|key
的含義|value
的含義|只接收一個(gè)變量時(shí)|
|—|—|—|—|
|字符串|字節(jié)索引 (index)|Unicode 碼點(diǎn) (rune) 的拷貝|key
(索引)|
|數(shù)組 / 切片|元素索引 (index)|元素值的拷貝|key
(索引)|
|Map|map 的鍵 (key)|map 的值的拷貝|key
(map 的鍵)|
|Channel|(無 key)|從 channel 接收到的值|value
(接收到的值)|
5、 處理中文字符
Go 語言的字符串是 UTF-8 編碼的字節(jié)序列。一個(gè)英文字母占 1 個(gè)字節(jié),而一個(gè)中文字符通常占 3 個(gè)字節(jié)。
如果使用傳統(tǒng)的 for i := 0; i < len(str); i++
或單返回值的 for range
來遍歷包含中文的字符串,由于是按字節(jié)索引,會導(dǎo)致中文字符被“撕裂”而產(chǎn)生亂碼。
正確處理中文的方式:
for range
在設(shè)計(jì)上已經(jīng)完美地處理了多字節(jié)字符。它能自動識別一個(gè)完整字符所占的字節(jié)數(shù),并正確地返回其 Unicode 碼點(diǎn)和起始索引。
5.1 方式一:使用雙變量 for range (推薦)
可以看到,索引值按 3 遞增,for range
準(zhǔn)確地跳過了每個(gè)中文字符的字節(jié)。
5.2 方式二:轉(zhuǎn)換為 []rune 切片
如果確實(shí)需要在處理中文字符時(shí)獲得連續(xù)的字符索引(0, 1, 2, …),可以先將字符串轉(zhuǎn)換為 rune
切片。
為了代碼的簡潔和高效,當(dāng)需要遍歷字符串中的字符時(shí),強(qiáng)烈推薦直接使用 for key, value := range str
的形式。
5、continue 和 break 語句
在循環(huán)過程中,有時(shí)我們需要更精細(xì)地控制循環(huán)的執(zhí)行流程,而不是簡單地等待循環(huán)條件自然結(jié)束。Go 語言提供了 break
和 continue
兩個(gè)關(guān)鍵字來實(shí)現(xiàn)這一目標(biāo)。
1、break:終止循環(huán)
break
語句用于立即終止其所在的最內(nèi)層的 for
循環(huán)。一旦執(zhí)行 break
,程序?qū)⑻鲅h(huán)體,繼續(xù)執(zhí)行循環(huán)之后的代碼。
這在無限循環(huán)或需要在滿足特定內(nèi)部條件時(shí)提前退出的場景中非常有用。
在上面的例子中,循環(huán)會一直進(jìn)行,直到 round
的值達(dá)到 10,if
條件成立,break
語句被執(zhí)行,從而強(qiáng)制結(jié)束這個(gè)無限循環(huán)。
2、continue:跳過當(dāng)次迭代
continue
語句用于跳過當(dāng)前這次循環(huán)迭代中尚未執(zhí)行的代碼,并立即進(jìn)入下一次循環(huán)的迭代。
當(dāng)我們在循環(huán)中遇到某個(gè)特定條件,不希望執(zhí)行后續(xù)的邏輯,而是想直接開始下一輪時(shí),continue
就派上了用場。
例如,我們想打印 1 到 10,但跳過數(shù)字 5:
在這個(gè)例子中,當(dāng) i
等于 5 時(shí),continue
語句被觸發(fā),它使得當(dāng)次循環(huán)的 fmt.Println(i)
語句被忽略,程序直接跳轉(zhuǎn)到 for
循環(huán)的下一次迭代(i++
之后,i
變?yōu)?6)。
6、goto語句 (謹(jǐn)慎使用)
goto
是 Go 語言中的一個(gè)跳轉(zhuǎn)語句,它可以讓程序無條件地跳轉(zhuǎn)到函數(shù)內(nèi)的指定標(biāo)簽 (label) 處繼續(xù)執(zhí)行。
由于 goto
會破壞程序的正常執(zhí)行流程,過度使用會導(dǎo)致代碼邏輯混亂,可讀性極差(即所謂的“面條代碼”),因此強(qiáng)烈不建議濫用。絕大多數(shù)情況下,我們都可以通過 if
、for
、return
等結(jié)構(gòu)來更好地實(shí)現(xiàn)邏輯。
1、goto 的基本用法
goto
的語法包含兩部分:goto label;
和 label:
。
定義標(biāo)簽:
label:
是一個(gè)標(biāo)識符,后跟一個(gè)冒號,放置在函數(shù)內(nèi)某行代碼的前面。執(zhí)行跳轉(zhuǎn):
goto label;
語句會使程序立即跳轉(zhuǎn)到label:
所在的位置。
一個(gè)主要的應(yīng)用場景是從嵌套的深層循環(huán)中一次性跳出。我們知道,break
只能跳出其所在的最內(nèi)層循環(huán),如果想直接終止所有循環(huán),goto
提供了一種解決方案。
在上面的例子中,當(dāng)內(nèi)層循環(huán)的 j
首次等于 2 時(shí),goto Over
被執(zhí)行,程序立即跳出兩層循環(huán),直接執(zhí)行 Over:
標(biāo)簽下的 fmt.Println("任務(wù)結(jié)束")
。
2、goto 的合理使用場景
盡管 goto
名聲不佳,但在一些特定場景下,合理使用可以簡化代碼,最常見的便是統(tǒng)一的錯(cuò)誤處理。
當(dāng)一個(gè)函數(shù)中有多個(gè)可能出錯(cuò)的步驟,且每個(gè)錯(cuò)誤都需要進(jìn)行相似的清理工作時(shí),可以使用 goto
將所有錯(cuò)誤處理邏輯集中到一處。
即便如此,在現(xiàn)代 Go 編程中,使用 defer
語句來處理資源釋放通常是更推薦、更清晰的做法。
總而言之,請將 goto
視為一個(gè)最后的選擇,僅在它能顯著簡化代碼且不降低可讀性的罕見情況下考慮使用。
7、switch 語句
switch
是 Go 中一種強(qiáng)大的分支控制語句。它提供了一種比一長串 if-else if
鏈更清晰、更易讀的方式來對一個(gè)表達(dá)式的多種可能的值進(jìn)行判斷。
1、switch 的基礎(chǔ)語法
switch expression { case value1: // expression 的值等于 value1 時(shí)執(zhí)行 case value2: // expression 的值等于 value2 時(shí)執(zhí)行 ... default: // 所有 case 都不匹配時(shí)執(zhí)行 }
expression
:一個(gè)表達(dá)式,其結(jié)果將與各個(gè)case
的值進(jìn)行比較。case value
:每個(gè)case
定義了一個(gè)要比較的值。default
:一個(gè)可選的子句,當(dāng)沒有任何case
匹配時(shí)執(zhí)行,類似于if-else
中的else
。自動
break
:與 C 或 Java 不同,Go 的switch
在每個(gè)case
塊的末尾自動包含了一個(gè)break
。這意味著一旦匹配到一個(gè)case
,執(zhí)行完其代碼后就會退出switch
,不會“掉落”到下一個(gè)case
。
讓我們來看一個(gè)根據(jù)星期輸出對應(yīng)英文的例子:
2、switch 的靈活用法
2.1 省略表達(dá)式
switch
后面的表達(dá)式可以省略。這種形式的 switch
等同于 switch true
,每個(gè) case
作為一個(gè)獨(dú)立的布爾表達(dá)式進(jìn)行判斷。這使得 switch
可以完全替代 if-else if-else
語句,并且通常更具可讀性。
例如,我們可以用它來進(jìn)行分?jǐn)?shù)等級評定:
2.2 一個(gè) case 匹配多個(gè)值
一個(gè) case
后面可以跟多個(gè)值,用逗號分隔。只要表達(dá)式的結(jié)果匹配其中任意一個(gè)值,該 case
就會被執(zhí)行。
至此,關(guān)于 Go 語言的基礎(chǔ)流程控制語句(if
、for
、switch
)及其相關(guān)的跳轉(zhuǎn)控制(break
、continue
、goto
)就介紹完畢了。掌握它們是編寫任何復(fù)雜程序的基石。
總結(jié)
到此這篇關(guān)于Go語言中條件判斷和for循環(huán)的文章就介紹到這了,更多相關(guān)Go條件判斷和for循環(huán)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
GoLang語法之標(biāo)準(zhǔn)庫fmt.Printf的使用
fmt包實(shí)現(xiàn)了類似C語言printf和scanf的格式化I/O,主要分為向外輸出內(nèi)容和獲取輸入內(nèi)容兩大部分,本文就來介紹一下GoLang語法之標(biāo)準(zhǔn)庫fmt.Printf的使用,感興趣的可以了解下2023-10-10讓GPT教你用go語言和C語言開發(fā)IDE配置學(xué)習(xí)
這篇文章主要介紹了讓GPT教你用go語言和C語言開發(fā)IDE配置學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10go內(nèi)存緩存BigCache之Entry封裝源碼閱讀
這篇文章主要介紹了go內(nèi)存緩存BigCache之Entry封裝源碼閱讀2023-09-09Golang中結(jié)構(gòu)體映射mapstructure庫深入詳解
mapstructure用于將通用的map[string]interface{}解碼到對應(yīng)的 Go 結(jié)構(gòu)體中,或者執(zhí)行相反的操作。很多時(shí)候,解析來自多種源頭的數(shù)據(jù)流時(shí),我們一般事先并不知道他們對應(yīng)的具體類型。只有讀取到一些字段之后才能做出判斷2023-01-01