Go之流程式控制制大全: 細節、示例與最佳實踐

来源:https://www.cnblogs.com/xfuture/archive/2023/09/14/17702277.html
-Advertisement-
Play Games

本文深入探討Go語言中的流程式控制制語法,包括基本的if-else條件分支、for迴圈、switch-case多條件分支,以及與特定數據類型相關的流程式控制制,如for-range迴圈和type-switch。文章還詳細描述了goto、fallthrough等跳轉語句的使用方法,通過清晰的代碼示例為讀者提供 ...


本文深入探討Go語言中的流程式控制制語法,包括基本的if-else條件分支、for迴圈、switch-case多條件分支,以及與特定數據類型相關的流程式控制制,如for-range迴圈和type-switch。文章還詳細描述了gotofallthrough等跳轉語句的使用方法,通過清晰的代碼示例為讀者提供了直觀的指導。

關註微信公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能實驗室成員,阿裡雲認證的資深架構師,項目管理專業人士,上億營收AI產品研發負責人。

file

引言

在電腦編程中,流程式控制制是核心的組成部分,它決定了程式應該如何根據給定的情況執行或決策。以下是Go語言所支持的流程式控制制結構的簡要概覽:

流程式控制制類型 代碼
if-else條件分支 if condition { } else { }
for迴圈 for initialization; condition; post { }
switch-case多條件分支 switch value { case v1: ... default: ... }
容器類型的for-range迴圈 for key, value := range container { }
介面類型的type-switch多條件分支 switch v := value.(type) { case T: ... }
通道類型的select-case多分支 select { case <-ch: ... default: ... }
break跳轉語句 break
continue跳轉語句 continue
goto跳轉語句 goto label
fallthrough跳轉語句 fallthrough

在後續部分,我們將深入探討每種流程式控制制結構的細節和應用案例,幫助你更好地理解和掌握Go語言的流程式控制制工具。


if-else條件分支

在Go中,if-else結構提供了條件判斷的基本方式。與許多其他編程語言類似,它的基本語法包括測試一個條件,並根據該條件的真假來執行相應的代碼塊。

基礎用法

流程式控制制類型 代碼
if if condition { }
if-else if condition { } else { }
if-else if-else if condition1 { } else if condition2 { } else { }

示例與說明

  1. if

    x := 10
    if x > 5 {
        fmt.Println("x is greater than 5")
    }
    

    當條件 x > 5 成立時,代碼會輸出 "x is greater than 5"。

  2. if-else

    x := 3
    if x > 5 {
        fmt.Println("x is greater than 5")
    } else {
        fmt.Println("x is not greater than 5")
    }
    

    因為 x > 5 的條件不成立,所以代碼會輸出 "x is not greater than 5"。

  3. if-else if-else

    x := 5
    if x > 10 {
        fmt.Println("x is greater than 10")
    } else if x < 5 {
        fmt.Println("x is less than 5")
    } else {
        fmt.Println("x is 5")
    }
    

    在這個示例中,由於 x 等於 5,代碼會輸出 "x is 5"。

帶初始化語句的if條件分支

在Go中,if語句可以包含一個初始化語句,通常用於定義在條件測試中使用的臨時變數。

流程式控制制類型 代碼
if with initialization if stmt; condition { }

示例與說明

if y := computeValue(); y > 10 {
    fmt.Println("y is greater than 10")
} else {
    fmt.Println("y is not greater than 10")
}

在這個示例中,我們首先調用 computeValue() 函數(假設它返回一個整數)並將結果賦值給變數 y。然後我們根據 y > 10 的條件來決定輸出什麼。這種結構允許我們在一個簡潔的語句中完成初始化和條件測試。

for迴圈

for迴圈是Go語言中的唯一迴圈結構,但其靈活性足以覆蓋其他編程語言中的多種迴圈結構。通過不同的組合,Go的for迴圈可以模擬傳統的whiledo-while迴圈。

基礎用法

流程式控制制類型 代碼
Basic loop for initialization; condition; post { }
While-like loop for condition { }
Infinite loop for { }

示例與說明

  1. Basic loop

    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }
    

    這是最常見的for迴圈形式,上述代碼會輸出0到4。

  2. While-like loop

    x := 5
    for x > 0 {
        fmt.Println(x)
        x--
    }
    

    這種結構模擬了傳統的while迴圈。上述代碼會輸出從5到1的數字。

  3. Infinite loop

    for {
        fmt.Println("This will run indefinitely!")
    }
    

    除非有break或其他控制語句,否則這種迴圈會無限運行。在某些情況下,這可以用於持續等待外部輸入或其他中斷。

range的for迴圈

Go語言提供了for-range結構,用於迭代數組、切片、字元串或映射的元素。

流程式控制制類型 代碼
Range loop for key, value := range container { }

示例與說明

nums := []int{1, 2, 3, 4, 5}
for idx, num := range nums {
    fmt.Printf("Index: %d, Value: %d\n", idx, num)
}

這個示例中,for-range迴圈迭代了一個整數切片,並輸出每個元素及其索引。同樣地,for-range可以用於迭代其他容器類型。


switch-case多條件分支

在Go語言中,switch-case結構提供了一個清晰的方式來進行多條件判斷。與其他語言的switch結構略有不同,Go的switch更加靈活,不僅可以用於常量和整數值,還可以用於更複雜的條件判斷。

基礎用法

流程式控制制類型 代碼
Basic switch switch expression { case value1: ... default: ... }
Multiple values switch expression { case val1, val2: ... }
No expression switch { case condition1: ... }

示例與說明

  1. Basic switch

    fruit := "apple"
    switch fruit {
    case "banana":
        fmt.Println("This is a banana.")
    case "apple":
        fmt.Println("This is an apple.")
    default:
        fmt.Println("Unknown fruit.")
    }
    

    上述代碼會輸出 "This is an apple.",因為 fruit 的值是 "apple"。

  2. Multiple values

    day := 2
    switch day {
    case 1, 7:
        fmt.Println("Weekend")
    case 2, 3, 4, 5, 6:
        fmt.Println("Weekday")
    default:
        fmt.Println("Invalid day")
    }
    

    這個示例中,我們檢查 day 是否是工作日還是周末。上述代碼會輸出 "Weekday"。

  3. No expression

    x := 10
    switch {
    case x > 5:
        fmt.Println("x is greater than 5")
    case x < 5:
        fmt.Println("x is less than 5")
    default:
        fmt.Println("x is 5")
    }
    

    在這種形式中,switch沒有伴隨的表達式,它僅僅評估case後的條件。上述代碼會輸出 "x is greater than 5"。

fallthrough關鍵字

在Go中,switchcase預設不會"貫穿"(即一旦匹配到一個case,它就會退出switch,不會執行後續的case)。如果你想繼續執行下一個case,你需要使用fallthrough關鍵字。

流程式控制制類型 代碼
Using fallthrough case value: ... fallthrough ...

示例與說明

value := 5
switch value {
case 5:
    fmt.Println("Value is 5")
    fallthrough
case 6:
    fmt.Println("Value is 6 or it fallthrough from 5")
default:
    fmt.Println("Another value")
}

上述代碼會連續輸出 "Value is 5" 和 "Value is 6 or it fallthrough from 5",因為fallthrough使得程式繼續執行下一個case。


容器類型的for-range迴圈

在Go中,for-range結構是處理容器類型(如數組、切片、字元串和映射)的強大工具。它可以非常方便地遍歷容器中的所有元素,無需手動處理索引或鍵。

數組和切片

流程式控制制類型 代碼
遍曆數組或切片 for idx, value := range arrayOrSlice { }

示例與說明

nums := []int{1, 2, 3, 4, 5}
for idx, num := range nums {
    fmt.Printf("Index: %d, Value: %d\n", idx, num)
}

此代碼遍歷nums切片的每一個元素,輸出其索引和值。
file

示例與說明

str := "hello"
for idx, char := range str {
    fmt.Printf("Index: %d, Char: %c\n", idx, char)
}

此代碼遍歷str字元串中的每個字元,並輸出其索引和字元值。

file

m := map[string]int{"a": 1, "b": 2, "c": 3}
for key, value := range m {
    fmt.Printf("Key: %s, Value: %d\n", key, value)
}

此代碼遍歷映射m中的每個鍵值對,輸出其鍵和值。
總的來說,for-range結構為Go程式員提供了一個簡單而強大的方式來遍歷和操作容器類型的數據。通過簡潔的語法,我們可以有效地處理各種容器,而無需擔心複雜的索引和邊界條件。

介面類型的type-switch多條件分支

在Go語言中,介面類型允許我們處理多種不同的數據類型,但有時我們需要知道介面變數的具體類型。這時,type-switch結構提供了一種優雅的方式來進行類型判斷和分支處理。

基礎用法

流程式控制制類型 代碼
type-switch switch v := i.(type) { case T: ... default: ... }

示例與說明

  1. 基礎type-switch

    var i interface{} = "hello"
    
    switch v := i.(type) {
    case int:
        fmt.Printf("It's an int with value %d\n", v)
    case string:
        fmt.Printf("It's a string with value %s\n", v)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
    

    此代碼首先聲明瞭一個介面類型的變數i並賦值為字元串"hello"。然後,使用type-switch來檢查i的動態類型。上述代碼將輸出:"It's a string with value hello"。

type-switch中的其他用法

type-switch不僅限於基本類型,還可以用於自定義類型、結構體等。

流程式控制制類型 代碼
自定義類型 case CustomType: ...
結構體 case structType: ...

示例與說明

  1. 自定義類型和結構體

    type MyString string
    type MyStruct struct {
        Field int
    }
    
    var i interface{} = MyString("hello")
    
    switch v := i.(type) {
    case MyString:
        fmt.Printf("It's a MyString with value %s\n", string(v))
    case MyStruct:
        fmt.Printf("It's a MyStruct with field value %d\n", v.Field)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
    

    在這個示例中,我們定義了一個自定義類型MyString和一個結構體MyStruct。然後,我們再次使用type-switch來檢查介面變數i的類型。給定的代碼將輸出:"It's a MyString with value hello"。

總的來說,type-switch結構為Go開發人員提供了一種清晰、簡潔的方式來判斷介面變數的動態類型,併進行分支處理。掌握這一結構對於在Go中正確處理介面和多態性至關重要。


通道類型的select-case多分支

Go語言中的select關鍵字是用於處理多個通道的讀/寫操作。當我們需要同時從多個通道接收或向多個通道發送數據時,select結構提供了一種方式來處理這些操作,使我們可以在一個通道準備好時執行相應的操作。

基礎用法

流程式控制制類型 代碼
select-case select { case operation1: ... case operation2: ... }

示例與說明

  1. 基礎select-case

    ch1 := make(chan int, 1)
    ch2 := make(chan string, 1)
    ch1 <- 1
    ch2 <- "hello"
    
    select {
    case i := <-ch1:
        fmt.Printf("Received from ch1: %d\n", i)
    case s := <-ch2:
        fmt.Printf("Received from ch2: %s\n", s)
    default:
        fmt.Println("No data received")
    }
    

    這段代碼定義了兩個通道,分別發送一個整數和一個字元串。使用select結構,程式嘗試從ch1ch2中接收數據。此代碼可能會輸出ch1ch2的數據,因為select會隨機選擇一個可用的case執行。

使用default

select結構中,可以使用default語句來處理當所有通道都不可用時的情況。

示例與說明

  1. 使用default

    ch := make(chan int, 1)
    
    select {
    case i := <-ch:
        fmt.Printf("Received from ch: %d\n", i)
    default:
        fmt.Println("No data available")
    }
    

    在這個例子中,我們嘗試從通道ch中接收數據。但由於沒有數據發送到該通道,程式將輸出"No data available"。

使用select進行超時處理

利用select結構,我們還可以輕鬆實現超時機制。

示例與說明

  1. 超時處理

    ch := make(chan int, 1)
    go func() {
        time.Sleep(2 * time.Second)
        ch <- 1
    }()
    
    select {
    case i := <-ch:
        fmt.Printf("Received from ch: %d\n", i)
    case <-time.After(1 * time.Second):
        fmt.Println("Timeout!")
    }
    

    這段代碼中,我們試圖從通道ch中接收數據,但我們只等待1秒。使用time.After函數,我們可以輕鬆實現超時邏輯。如果1秒內沒有從ch中接收到數據,程式將輸出"Timeout!"。

總之,select-case結構為Go開發人員處理多個通道提供了一種非常方便的方式。它不僅允許我們併發地處理多個通道,還可以輕鬆實現超時和預設操作,使併發編程變得簡單而強大。


break跳轉語句

在Go語言中,break語句主要用於提前結束一個迴圈或switchselect等代碼塊的執行。它使我們可以在滿足特定條件時跳出當前執行的代碼塊。

基礎用法

流程式控制制類型 代碼
break break

示例與說明

  1. 在for迴圈中使用break

    for i := 0; i < 10; i++ {
        if i == 5 {
            break
        }
        fmt.Println(i)
    }
    

    這段代碼將列印從0到4的數字。當i等於5時,break語句會被觸發,從而提前結束迴圈。

  2. 在switch中使用break

    switch 2 {
    case 1:
        fmt.Println("Case 1")
    case 2:
        fmt.Println("Case 2")
        if true {
            break
        }
        fmt.Println("This won't be printed")
    case 3:
        fmt.Println("Case 3")
    }
    

    在此示例中,當匹配到case 2時,程式會輸出"Case 2",然後由於break語句,fmt.Println("This won't be printed")將不會被執行。

帶標簽的break

在Go中,你還可以使用帶標簽的break語句來跳出外層迴圈或其他代碼塊。

示例與說明

  1. 使用帶標簽的break

    outerLoop:
    for i := 0; i < 5; i++ {
        for j := 0; j < 5; j++ {
            if i*j == 6 {
                break outerLoop
            }
            fmt.Println(i, j)
        }
    }
    

    在上述代碼中,我們有兩個嵌套的for迴圈。當i*j等於6時,帶標簽的break語句會被觸發,這將導致外層的for迴圈提前結束。

總體上說,break語句在Go中提供了一種靈活的方式來控制代碼塊的執行流程。它在迴圈、switchselect等結構中都有著廣泛的應用,使我們可以根據特定的條件提前結束代碼塊的執行。


continue跳轉語句

在Go語言中,continue語句被用於跳過當前迴圈的剩餘語句,並開始下一次迴圈。不同於break語句,它並不會結束整個迴圈,而只是跳過當前的迭代。

基礎用法

流程式控制制類型 代碼
continue continue

示例與說明

  1. 在for迴圈中使用continue

    for i := 0; i < 10; i++ {
        if i%2 == 0 {
            continue
        }
        fmt.Println(i)
    }
    

    上述代碼將列印出0到9之間的所有奇數。當i是偶數時,continue語句會被觸發,從而跳過當前迴圈的剩餘部分。

  2. 在for-range迴圈中使用continue

    arr := []int{1, 2, 3, 4, 5}
    for idx, val := range arr {
        if val == 3 {
            continue
        }
        fmt.Printf("arr[%d] = %d\n", idx, val)
    }
    

    這段代碼遍歷一個整數切片,並列印除3之外的所有元素的索引和值。當元素值為3時,continue語句會被觸發,從而跳過當前迭代。

帶標簽的continue

break語句類似,continue也支持帶標簽的形式,從而可以在多層嵌套的迴圈中指定跳轉到哪個外層迴圈的下一次迭代。

示例與說明

  1. 使用帶標簽的continue

    outerLoop:
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            if i == 1 && j == 1 {
                continue outerLoop
            }
            fmt.Println(i, j)
        }
    }
    

    在這個例子中,我們有兩個嵌套的for迴圈。當i等於1並且j等於1時,帶標簽的continue語句會被觸發,這會導致直接跳到外層迴圈的下一次迭代,而內層迴圈的剩餘迭代會被跳過。

總之,continue語句為Go開發人員提供了一種方式,可以在滿足特定條件時跳過迴圈的某次迭代。這使得我們可以更靈活地控制迴圈的執行流程。


goto跳轉語句

在Go語言中,goto 語句允許程式在執行時跳轉到指定的標簽。儘管goto 語句在現代編程中不那麼常用,並且在某些情況下可能引發困惑或使代碼難以閱讀,但在某些特定場景中,它可能是有用的。

基礎用法

流程式控制制類型 代碼
goto goto

示例與說明

  1. 簡單的goto使用

    func main() {
        fmt.Println("Start")
        goto end
        fmt.Println("This won't be printed")
    end:
        fmt.Println("End")
    }
    

    在此示例中,程式首先列印"Start",然後跳轉到end標簽,繼續執行下麵的代碼。因此,fmt.Println("This won't be printed") 不會被執行。

  2. 使用goto進行錯誤處理

    func divide(x, y int) (int, error) {
        if y == 0 {
            return 0, errors.New("Cannot divide by zero")
        }
        return x / y, nil
    }
    
    func main() {
        result, err := divide(10, 0)
        if err != nil {
            goto handleErr
        }
        fmt.Println("Result:", result)
        return
    
    handleErr:
        fmt.Println("Error:", err)
    }
    

    在這個例子中,我們使用goto語句來跳轉到錯誤處理部分。這種做法在某些情況下可以使錯誤處理更為集中。

儘管goto語句在Go中是可用的,但開發者通常建議在只有真正需要的情況下使用它,因為不當的使用可能導致代碼難以理解和維護。當您可以使用其他結構(如ifforswitch)來實現相同的結果時,最好避免使用goto


fallthrough跳轉語句

在Go的switch語句中,一旦某個case匹配成功,後續的case將不會再被檢查或執行。然而,Go提供了一個特有的關鍵字:fallthrough,它可以強制執行緊跟它後面的case,無論該case是否匹配。

基礎用法

流程式控制制類型 代碼
fallthrough fallthrough

示例與說明

  1. 基礎的fallthrough使用

    x := 10
    
    switch x {
    case 10:
        fmt.Println("x is 10")
        fallthrough
    case 20:
        fmt.Println("x is 20")
    default:
        fmt.Println("x is neither 10 nor 20")
    }
    

    在此示例中,x的值是10,所以程式會首先列印"x is 10"。由於第一個case後面有fallthrough語句,程式繼續執行下一個case,即使x的值並不是20,所以還會列印"x is 20"。

  2. fallthrough在非連續case中的使用

    y := "apple"
    
    switch y {
    case "banana":
        fmt.Println("y is banana")
    case "apple":
        fmt.Println("y is apple")
        fallthrough
    case "orange":
        fmt.Println("y is orange")
    default:
        fmt.Println("y is neither banana, apple, nor orange")
    }
    

    在這個例子中,當y的值為"apple"時,會列印"y is apple"。然後,由於存在fallthrough語句,"y is orange"也會被列印,即使y的值並不是"orange"。

需要註意的是,雖然fallthrough提供了一種特殊的控制流,但在大多數場景中,過度或不恰當的使用可能導致代碼難以閱讀和理解。因此,推薦在真正需要時才使用它,並確保代碼的意圖清晰可見。


關註微信公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能實驗室成員,阿裡雲認證的資深架構師,項目管理專業人士,上億營收AI產品研發負責人。

如有幫助,請多關註
個人微信公眾號:【TechLeadCloud】分享AI與雲服務研發的全維度知識,談談我作為TechLead對技術的獨特洞察。
TeahLead KrisChang,10+年的互聯網和人工智慧從業經驗,10年+技術和業務團隊管理經驗,同濟軟體工程本科,復旦工程管理碩士,阿裡雲認證雲服務資深架構師,上億營收AI產品業務負責人。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 電腦思維和人的思維的不同 對於一個算式3+2*(4-3)/5 人的思維是根據括弧和符號優先順序,優先計算括弧中的數據,在進行乘法和除法,在處理加法運算 但是電腦的思維是線性的,電腦會按照算式的前後順序,從前往後進行運算,這樣會導致運算結果錯誤 電腦如何套用人的運算思維 想要讓電腦具有人的”思 ...
  • 應大家需求,出一個 wp 自動發佈每日 60 秒讀懂世界文章的教程. 1.複製下方的 php 代碼 <?php $date = file_get_contents("https://www.zhihu.com/api/v4/columns/c_1261258401923026944/items"); ...
  • 1、UIScrollView增加了屬性allowsKeyboardScrolling表示是否根據連接的物理鍵盤的方向鍵而滾動。 import UIKit class ViewController: UIViewController { lazy var scrollView: UIScrollVie ...
  • 1.ioc 1 pom導包spring-mvc 2 創建資源文件xml、pojo對象() 3 資源文件中配置bean,對pojo對象屬性 4 測試中直接getBean獲取。 1.1 一些不重要的 取別名:在資源文件中取別名,一種是直接在bean標簽中用name,另一種是單獨設置標簽alias 合併配 ...
  • 線程間共用數據的問題 多線程之間共用數據,最大的問題便是數據競爭導致的異常問題。多個線程操作同一塊資源,如果不做任何限制,那麼一定會發生錯誤。例如: 1 int g_nResource = 0; 2 void thread_entry() 3 { 4 for (int i = 0; i < 1000 ...
  • 原本你寫的程式是靜態鏈接的系統的vulkan-1.dll,如果系統不存在vulkan-1.dll,則會直接崩潰。 關於將ncnn靜態鏈接vulkan改成動態載入vulkan的形式,然後提供這兩個函數 bool ncnn::has_vulkan(); void ncnn::use_vulkan(boo ...
  • 1 前言 高性能的HTTP和反向代理伺服器,Nginx用來: 搭建Web Server 作負載均衡 供配置的日誌欄位豐富,從各類HTTP頭部到內部性能數據都有 Nginx的訪問日誌中,存在499狀態碼的日誌。但常見4xx狀態碼只有400、401、403、404等,499並未在HTTP RFC文檔。這 ...
  • 本篇咱們從零開發一個quarkus應用,支持虛擬線程響應web服務,響應式操作postgresql資料庫,並且在quarkus官方還未支持的情況下,率先並將其製作成docker鏡像 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...