有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

理解Go流程控制與快樂(lè)路徑原則

 更新時(shí)間:2023年10月12日 08:40:04   作者:賈維斯Echo  
這篇文章主要為大家介紹了Go流程控制與快樂(lè)路徑原則的原理解析,
有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、流程控制基本介紹

流程控制是每種編程語(yǔ)言控制邏輯走向和執(zhí)行次序的重要部分,流程控制可以說(shuō)是一門(mén)語(yǔ)言的“經(jīng)脈”。

那么 Go 語(yǔ)言對(duì)分支與循環(huán)兩種控制結(jié)構(gòu)的支持是怎么樣的呢?針對(duì)程序的分支結(jié)構(gòu),Go 提供了 if 和 switch-case 兩種語(yǔ)句形式;我們就先從 Go 語(yǔ)言分支結(jié)構(gòu)之一的 if 語(yǔ)句開(kāi)始講起。

二、if 語(yǔ)句

2.1 if 語(yǔ)句介紹

if 語(yǔ)句是 Go 語(yǔ)言中提供的一種分支控制結(jié)構(gòu),它也是 Go 中最常用、最簡(jiǎn)單的分支控制結(jié)構(gòu)。它會(huì)根據(jù)布爾表達(dá)式的值,在兩個(gè)分支中選擇一個(gè)執(zhí)行。

2.2 單分支結(jié)構(gòu)的 if 語(yǔ)句形式

單分支結(jié)構(gòu)的if語(yǔ)句包含一個(gè)條件表達(dá)式和一個(gè)要執(zhí)行的代碼塊。如果條件表達(dá)式的值為true,則執(zhí)行代碼塊。如果條件表達(dá)式的值為false,則代碼塊將被跳過(guò)。以下是單分支結(jié)構(gòu)的if語(yǔ)句的一般形式:

if boolean_expression {
    // 新分支
}
// 原分支

這個(gè) if 語(yǔ)句中的代碼執(zhí)行流程就等價(jià)于下面這幅流程圖:

  • boolean_expression是一個(gè)布爾表達(dá)式,通常返回truefalse
  • 如果boolean_expression的值為true,則執(zhí)行// 當(dāng)條件為真時(shí)執(zhí)行的代碼部分的代碼塊。
  • 如果boolean_expression的值為false,則代碼塊將被跳過(guò),繼續(xù)執(zhí)行下一個(gè)語(yǔ)句。

2.3 Go 的 if 語(yǔ)句的特點(diǎn)

2.3.1 分支代碼塊左大括號(hào)與if同行

if 語(yǔ)句的分支代碼塊的左大括號(hào)與 if 關(guān)鍵字在同一行上,這是 Go 代碼風(fēng)格的統(tǒng)一要求,gofmt 工具會(huì)幫助我們實(shí)現(xiàn)這一點(diǎn);

2.3.2 條件表達(dá)式不需要括號(hào)

if 語(yǔ)句的布爾表達(dá)式整體不需要用括號(hào)包裹,這使得代碼更加簡(jiǎn)潔。而且,if 關(guān)鍵字后面的條件判斷表達(dá)式的求值結(jié)果必須是布爾類(lèi)型,即要么是 true,要么是 false

if runtime.GOOS == "darwin" {
    println("we are on MacOS")
}

如果判斷的條件比較多,我們可以用多個(gè)邏輯操作符連接起多個(gè)條件判斷表達(dá)式,比如這段代碼就是用了多個(gè)邏輯操作符 && 來(lái)連接多個(gè)布爾表達(dá)式:

if (runtime.GOOS == "darwin") && (runtime.GOARCH == "amd64") &&
        (runtime.Compiler != "gccgo") {
        println("we are using standard go compiler on Mac os for amd64")
    }

上面示例代碼中的每個(gè)布爾表達(dá)式都被小括號(hào)括上了,這是為了降低你在閱讀和理解這段代碼時(shí),面對(duì)操作符優(yōu)先級(jí)的心智負(fù)擔(dān)。

三、操作符

3.1 邏輯操作符

邏輯操作符除了上面的 && 之外,Go 還提供了另外兩個(gè)邏輯操作符,如下表:

3.2 操作符的優(yōu)先級(jí)

一元操作符,比如上面的邏輯非操作符,具有最高優(yōu)先級(jí),其他操作符的優(yōu)先級(jí)如下:

優(yōu)先級(jí)(從高到低)操作符列表
5*, /, %, <<, >>, &, &^
4+, -
3!=, ==, <, <=, >, >=
2&&
1\
  • 優(yōu)先級(jí)5的是乘、除、取模和位操作符
  • 優(yōu)先級(jí)4的是加法和減法運(yùn)算符
  • 優(yōu)先級(jí)3的是關(guān)系和相等運(yùn)算符
  • 優(yōu)先級(jí)2的是邏輯與
  • 優(yōu)先級(jí)最低的是邏輯或

操作符優(yōu)先級(jí)決定了操作數(shù)優(yōu)先參與哪個(gè)操作符的求值運(yùn)算,我們以下面代碼中 if 語(yǔ)句的布爾表達(dá)式為例:

func main() {
    a, b := false,true
    if a && b != true {
        println("(a && b) != true")
        return
    }
    println("a && (b != true) == false")
}

這段代碼會(huì)輸出得到的是 a && (b != true) == false。這是為什么呢?

這段代碼的關(guān)鍵就在于,if 后面的布爾表達(dá)式中的操作數(shù) b 是先參與 && 的求值運(yùn)算,還是先參與!= 的求值運(yùn)算。根據(jù)前面的操作符優(yōu)先級(jí)表,我們知道,!= 的優(yōu)先級(jí)要高于 &&,因此操作數(shù) b 先參與的是!= 的求值運(yùn)算,這樣 if 后的布爾表達(dá)式就等價(jià)于 a && (b != true) 。

針對(duì)以上問(wèn)題,推薦在 if 布爾表達(dá)式中,使用帶有小括號(hào)的子布爾表達(dá)式來(lái)清晰地表達(dá)判斷條件。

這樣做不僅可以消除了自己記住操作符優(yōu)先級(jí)的學(xué)習(xí)負(fù)擔(dān),當(dāng)其他人閱讀你的代碼時(shí),也可以很清晰地看出布爾表達(dá)式要表達(dá)的邏輯關(guān)系,這能讓我們代碼的可讀性更好,更易于理解,不會(huì)因記錯(cuò)操作符優(yōu)先級(jí)順序而產(chǎn)生錯(cuò)誤的理解。

三、if 多(N)分支結(jié)構(gòu)

3.1 if else(分支結(jié)構(gòu))

Go語(yǔ)言中if else(分支結(jié)構(gòu))條件判斷的格式如下:

if boolean_expression {
  // 分支1
} else {
  // 分支2
}

3.2 (N)分支結(jié)構(gòu)(if ... else if ... else)

if條件(N)分支結(jié)構(gòu)格式如下:

if boolean_expression1 {
  // 分支1
} else if boolean_expression2 {
  // 分支2

... ...

} else if boolean_expressionN {
  // 分支N
} else {
  // 分支N+1
}

我們以下面這個(gè)四分支的代碼為例,看看怎么拆解這個(gè)多分支結(jié)構(gòu):

if boolean_expression1 {
    // 分支1
} else if boolean_expression2 {
    // 分支2
} else if boolean_expression3 {
    // 分支3
} else {
    // 分支4
}

以下是一個(gè)示例,演示如何使用if-else結(jié)構(gòu)來(lái)判斷一個(gè)分?jǐn)?shù)的等級(jí):

package main
import "fmt"
func main() {
    score := 85
    if score >= 90 {
        fmt.Println("A")
    } else if score >= 80 {
        fmt.Println("B")
    } else if score >= 70 {
        fmt.Println("C")
    } else {
        fmt.Println("D")
    }
}

四、if 語(yǔ)句的自用變量

無(wú)論是單分支、二分支還是多分支結(jié)構(gòu),我們都可以在 if 后的布爾表達(dá)式前,進(jìn)行一些變量的聲明,在 if 布爾表達(dá)式前聲明的變量,叫 if 語(yǔ)句的自用變量。顧名思義,這些變量只可以在 if 語(yǔ)句的代碼塊范圍內(nèi)使用,比如下面代碼中的變量 a、b 和 c:

func main() {
    if a, c := f(), h(); a > 0 {
        println(a)
    } else if b := f(); b > 0 {
        println(a, b)
    } else {
        println(a, b, c)
    }
}

我們可以看到自用變量聲明的位置是在每個(gè) if 語(yǔ)句的后面,布爾表達(dá)式的前面,而且,由于聲明本身是一個(gè)語(yǔ)句,所以我們需要把它和后面的布爾表達(dá)式通過(guò)分號(hào)分隔開(kāi)。

在 if 語(yǔ)句中聲明自用變量是 Go 語(yǔ)言的一個(gè)慣用法,這種使用方式直觀上可以讓開(kāi)發(fā)者有一種代碼行數(shù)減少的感覺(jué),提高可讀性。同時(shí),由于這些變量是 if 語(yǔ)句自用變量,它的作用域僅限于 if 語(yǔ)句的各層隱式代碼塊中,if 語(yǔ)句外部無(wú)法訪問(wèn)和更改這些變量,這就讓這些變量具有一定隔離性,這樣你在閱讀和理解 if 語(yǔ)句的代碼時(shí)也可以更聚焦。

五、if 語(yǔ)句的“快樂(lè)路徑”原則

上面我們已經(jīng)學(xué)了 if 分支控制結(jié)構(gòu)的三種形式了,從可讀性上來(lái)看,單分支結(jié)構(gòu)要優(yōu)于二分支結(jié)構(gòu),二分支結(jié)構(gòu)又優(yōu)于多分支結(jié)構(gòu)。那么顯然,我們?cè)谌粘>幋a中要減少多分支結(jié)構(gòu),甚至是二分支結(jié)構(gòu)的使用,這會(huì)有助于我們編寫(xiě)出優(yōu)雅、簡(jiǎn)潔、易讀易維護(hù)且不易錯(cuò)的代碼。

首先,我們來(lái)看一段偽代碼段1:

//偽代碼段1:
func doSomething() error {
  if errorCondition1 {
    // some error logic
    ... ...
    return err1
  }
  // some success logic
  ... ...
  if errorCondition2 {
    // some error logic
    ... ...
    return err2
  }
  // some success logic
  ... ...
  return nil
}

我們看到單分支控制結(jié)構(gòu)的偽代碼段 1 有這幾個(gè)特點(diǎn):

  • 沒(méi)有使用 else 分支,失敗就立即返回;
  • “成功”邏輯始終“居左”并延續(xù)到函數(shù)結(jié)尾,沒(méi)有被嵌入到 if 的布爾表達(dá)式為 true 的代碼分支中;
  • 整個(gè)代碼段布局扁平,沒(méi)有深度的縮進(jìn);
  • 代碼的可讀性很高

我們來(lái)看一段偽代碼段2:

// 偽代碼段2:
func doSomething() error {
  if successCondition1 {
    // some success logic
    ... ...
    if successCondition2 {
      // some success logic
      ... ...
      return nil
    } else {
      // some error logic
      ... ...
      return err2
    }
  } else {
    // some error logic
    ... ...
    return err1
  }
}

偽代碼段 2 實(shí)現(xiàn)了同樣邏輯碼段 1,就使用了帶有嵌套的二分支結(jié)構(gòu),它的特點(diǎn)如下:

  • 整個(gè)代碼段呈現(xiàn)為“鋸齒狀”,有深度縮進(jìn);
  • “成功”邏輯被嵌入到 if 的布爾表達(dá)式為 true 的代碼分支中;

很明顯,偽代碼段 1 的邏輯更容易理解,也更簡(jiǎn)潔。Go 社區(qū)把這種 if 語(yǔ)句的使用方式稱(chēng)為 if 語(yǔ)句的“快樂(lè)路徑(Happy Path)”原則,所謂“快樂(lè)路徑”也就是成功邏輯的代碼執(zhí)行路徑,它的特點(diǎn)是這樣的:

  • 僅使用單分支控制結(jié)構(gòu);
  • 當(dāng)布爾表達(dá)式求值為 false 時(shí),也就是出現(xiàn)錯(cuò)誤時(shí),在單分支中快速返回;
  • 正常邏輯在代碼布局上始終“靠左”,這樣讀者可以從上到下一眼看到該函數(shù)正常邏輯的全貌;
  • 函數(shù)執(zhí)行到最后一行代表一種成功狀態(tài)。

Go 社區(qū)推薦 Gopher 們?cè)谑褂?if 語(yǔ)句時(shí)盡量符合這些原則,如果你的函數(shù)實(shí)現(xiàn)代碼不符合“快樂(lè)路徑”原則,你可以按下面步驟進(jìn)行重構(gòu):

  • 嘗試將“正常邏輯”提取出來(lái),放到“快樂(lè)路徑”中;
  • 如果無(wú)法做到上一點(diǎn),很可能是函數(shù)內(nèi)的邏輯過(guò)

以上就是Go流程控制與快樂(lè)路徑原則的詳細(xì)內(nèi)容,更多關(guān)于Go流程控制路徑原則的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用golang實(shí)現(xiàn)在屏幕上打印進(jìn)度條的操作

    使用golang實(shí)現(xiàn)在屏幕上打印進(jìn)度條的操作

    這篇文章主要介紹了使用golang實(shí)現(xiàn)在屏幕上打印進(jìn)度條的操作,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Golang新提案:panic?能不能加個(gè)?PanicError?

    Golang新提案:panic?能不能加個(gè)?PanicError?

    這篇文章主要為大家介紹了Golang的新提案關(guān)于panic能不能加個(gè)PanicError的問(wèn)題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • go語(yǔ)言for循環(huán)中嵌套defer的執(zhí)行順序

    go語(yǔ)言for循環(huán)中嵌套defer的執(zhí)行順序

    在Go語(yǔ)言中,defer語(yǔ)句用于延遲函數(shù)調(diào)用的執(zhí)行,本文主要介紹了go語(yǔ)言for循環(huán)中嵌套defer的執(zhí)行順序,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • Golang 標(biāo)準(zhǔn)庫(kù) tips之waitgroup詳解

    Golang 標(biāo)準(zhǔn)庫(kù) tips之waitgroup詳解

    本篇文章給大家介紹Golang 標(biāo)準(zhǔn)庫(kù) tips之waitgroup的相關(guān)知識(shí),包括使用 channel 實(shí)現(xiàn) WaitGroup 的功能介紹,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • 使用go語(yǔ)言實(shí)現(xiàn)Redis持久化的示例代碼

    使用go語(yǔ)言實(shí)現(xiàn)Redis持久化的示例代碼

    redis 是一個(gè)內(nèi)存數(shù)據(jù)庫(kù),如果你把進(jìn)程殺掉,那么里面存儲(chǔ)的數(shù)據(jù)都會(huì)消失,那么這篇文章就是來(lái)解決 redis 持久化的問(wèn)題,本文給大家介紹了使用go語(yǔ)言實(shí)現(xiàn)Redis持久化,需要的朋友可以參考下
    2024-07-07
  • Go語(yǔ)言實(shí)現(xiàn)RSA加解密算法詳解

    Go語(yǔ)言實(shí)現(xiàn)RSA加解密算法詳解

    隨著互聯(lián)網(wǎng)的高速發(fā)展,人們對(duì)安全的要求也越來(lái)越高,加解密也變得越來(lái)越重要,本文主要為大家介紹了Go語(yǔ)言中實(shí)現(xiàn)RSA加解密與簽名驗(yàn)證算法,希望對(duì)大家有所幫助
    2023-06-06
  • golang 連接mongoDB的方法示例

    golang 連接mongoDB的方法示例

    這篇文章主要介紹了golang 連接mongoDB的方法示例,詳細(xì)的介紹了golang的基礎(chǔ)知識(shí)和連接mongoDB的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • golang 獲取字符串長(zhǎng)度的案例

    golang 獲取字符串長(zhǎng)度的案例

    這篇文章主要介紹了golang 獲取字符串長(zhǎng)度的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • 解決go mod私有倉(cāng)庫(kù)拉取的問(wèn)題

    解決go mod私有倉(cāng)庫(kù)拉取的問(wèn)題

    這篇文章主要介紹了解決go mod私有倉(cāng)庫(kù)拉取的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05
  • 基于go中fyne gui的通達(dá)信數(shù)據(jù)導(dǎo)出工具詳解

    基于go中fyne gui的通達(dá)信數(shù)據(jù)導(dǎo)出工具詳解

    這篇文章主要介紹了基于go中fyne gui的通達(dá)信數(shù)據(jù)導(dǎo)出工具,這是一個(gè)用 Go 語(yǔ)言開(kāi)發(fā)的通達(dá)信數(shù)據(jù)導(dǎo)出工具,可以將通達(dá)信的本地?cái)?shù)據(jù)導(dǎo)出為多種格式,方便用戶(hù)進(jìn)行數(shù)據(jù)分析和處理,需要的朋友可以參考下
    2024-12-12

最新評(píng)論