iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0
自我挑戰組

Go in 3o系列 第 4

[Day04] Go in 30 - 變數與算符 part03 常數、列舉、Scope,套一些流程控制

  • 分享至 

  • xImage
  •  

本篇整理有關 Go 語言中常數、列舉和變數作用範圍的介紹,
並進入下一個篇章有關流程控制。

一、Go 常數、列舉、變數作用範圍

1.1 常數(constant)

在 Golang 中,常數是指在程式運行期間不會改變其值的變數。常數通常用於存儲不變的數值或值。以下是一些常數的特點和用法:

  • 常數聲明:使用 const 關鍵字來聲明常數,例如:const Pi = 3.14159265359。
  • 常數的數值可以是數字、字符串或布林值。
  • 常數是在編譯時計算的,不能在運行時改變。
  • 常數的值可以在不同的數據類型之間轉換,例如整數轉浮點數。

1.2 列舉(enum)

Golang 沒有內建的列舉型別(enum),但可以使用 const 常數和 iota 常數生成器來實現列舉的效果。以下是如何實現列舉的示例:

package main

import "fmt"

const (
    Sunday = iota // 0
    Monday        // 1
    Tuesday       // 2
    Wednesday     // 3
    Thursday      // 4
    Friday        // 5
    Saturday      // 6
)

func main() {
    fmt.Println(Sunday, Monday, Tuesday)
}

在上面的示例中,iota 用於自動遞增常數的值,從 0 開始。這樣可以方便地創建一組相關的常數,例如星期幾。

在 Golang 中,iota 是一個特殊的內建常數生成器。

以下是有關 iota 的重要特點和用法:

  • 自動遞增:iota 會自動遞增,從 0 開始,每次出現在 const 常數塊中時都會遞增一次。

  • 重置機制:iota 在不同的 const 常數塊中會被重置為 0,這使得可以在不同的塊中使用相同的 iota,並且每個塊都會有自己的獨立遞增序列。

const (
    Sunday = iota // 0
    Monday        // 1
    Tuesday       // 2
    Wednesday     // 3
    Thursday      // 4
    Friday        // 5
    Saturday      // 6
)

// 它是一行一行遞增,所以以下Monday Tuesday 是在同一行,所以他們都是 1
const (
    Sunday = iota // 0
    Monday, Tuesday        // 1
    Wednesday     // 2
    Thursday      // 3
    Friday        // 4
    Saturday      //5
)

1.3 變數作用範圍(scope)

在 Golang 中,變數的作用範圍(Scope)指的是變數在程式碼中可見和可訪問的區域。以下是一些有關變數作用範圍的重要概念:

  • 區域變數:在函數內聲明的變數是區域變數,它們只能在函數內部訪問。
  • 全域變數:在函數外部聲明的變數是全域變數,它們可以在整個程式中訪問。
  • 塊作用範圍:在控制結構(如條件語句和迴圈)內部聲明的變數具有塊作用範圍,只能在該控制結構內部訪問。
  • 函數作用範圍:函數參數和內部變數的作用範圍僅限於函數內部。
  • 隱藏變數:如果在內部作用範圍聲明了一個具有與外部作用範圍相同名稱的變數,則內部變數將隱藏外部變數。

變數的作用範圍是 Golang 程式碼中一個重要的概念,它確定了變數的可見性和生命週期。
理解變數作用範圍有助於避免命名衝突和確保程式碼的可維護性。

以上是有關 Golang 中常數、列舉和變數作用範圍的簡要介紹。

二、流程控制

流程控制使程式能夠根據不同的情況執行不同的程式碼路徑,實現更複雜和靈活的程式邏輯。不同的程式設計語言可能會有不同的語法和結構,但這些基本的流程控制概念是通用的,適用於各種程式設計語言。

在 Go 中,流程控制主要分為以下三大類別:

2.1 條件控制(Conditional Control):

if 陳述句:用於根據指定的條件來執行程式碼塊。
例如 :

package main

import "fmt"

func main() {
    age := 18
    if age >= 18 {
        fmt.Println("我已滿18歲")
    } else {
        fmt.Println("未滿18離開網站")
    }
}

2.2 迴圈(Looping):

for 迴圈:用於重複執行程式碼塊,可以是條件式的 for 迴圈,也可以是無限迴圈。

使用迴圈印出1~5

package main

import "fmt"

func main() {
    for i := 1; i <= 5; i++ {
        fmt.Println(i)
    }
}

無窮迴圈

package main

import "fmt"

func main() {
    for {
        fmt.Println("infinite loop")
    }
}

像是while的for loop
在Go語言中,你可以創建一個像while迴圈一樣運作的for迴圈,方法是省略初始化和後處理語句。
以下是基本結構:

for condition{
    // statement..
}

在這種類型的迴圈中,只要「條件」為true,迴圈內的程式碼就會持續執行。
一旦「條件」變為false,迴圈將終止。

package main

import "fmt"

func main() {
    i := 1
    for i <= 5 {
        fmt.Println(i)
        i++
    }
}

range 關鍵字:用於迭代集合(如 array、slice、map)的元素。

基本結構:

for i, j:= range rvariable{
   // statement..
}

我們來解釋這段程式碼的每個部分:

  • i 和 j:這些是用來接收range操作的結果的變數。通常情況下,i 代表索引,而 j 代表元素的值。你可以自行命名這兩個變數,只要它們的名稱在該範疇內是唯一的。

  • 使用了短變數宣告,其中 i 和 j 被宣告並初始化為range rvariable的結果。具體來說:i 被初始化為range rvariable中的元素索引(或key,如果是map)。j 被初始化為range rvariable中的元素

  • range rvariable:這部分表示我們要遍歷的可迭代的集合,它被稱為rvariable(你可以自行命名)。在這個例子中,rvariable 可能是一個陣列、切片、映射或其他支援range的資料結構。

  • {} 內的 // statement..:這個區塊代表在每一次迭代中要執行的程式碼。你可以在這個區塊中使用 i 和 j 這兩個變數來操作集合中的元素。

  • 在每一次迭代中,range會將 i 設置為元素的索引,並將 j 設置為元素的值。程式碼區塊內的程式碼將被執行,然後迭代將繼續到下一個元素,直到集合中的所有元素都被處理完畢。

package main

import "fmt"

func main() {
    numbers := []int{1, 2, 3, 4, 5}
    
    for index, value := range numbers {
        fmt.Printf("索引 %d 的值是 %d\n", index, value)
    }
}

2.3 跳躍控制(Jump Control):

  • break 陳述句:用於退出迴圈。
  • continue 陳述句:用於跳過迴圈的當前迭代。
  • goto 陳述句:用於無條件跳轉到程式碼的標籤位置。注意:在實際應用中,goto 很少被使用,因為它容易導致程式碼的不可讀性和錯誤。

break範例:

package main

import "fmt"

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

goto 範例:

package main

import "fmt"

func main() {
    i := 1
    
start:
    fmt.Println(i)
    i++
 
    if i <= 5 {
        goto start
    }
}

這個範例中,我們使用 goto 在程式碼中創建一個標籤 start,然後在迴圈中使用 goto 跳躍到這個標籤,以實現類似 for 迴圈的效果。

continue 範例 :

package main

import "fmt"

func main() {
    numbers := []int{1, 2, 3, 4, 5}
    
    for _, value := range numbers {
        if value % 2 == 0 {
            continue
        }
        fmt.Printf("%d 是奇數\n", value)
    }
}

輸出結果 :

https://ithelp.ithome.com.tw/upload/images/20230919/2016269344NdsLnkuL.png

ps. _底線的意思

for _, value := range numbers {
    // ...
}

在 Go 語言中,底線 _ 通常用作變數名稱,但具有特殊的含義:它是一個匿名的變數(blank identifier)。當我們不需要使用某個變數的值時,可以使用 _ 來忽略該值,這樣可以避免宣告變數但不使用它所引起的編譯錯誤

上述範例程式說明 :
這表示我們不care迭代中的索引值,我們只關心 value 的值。這樣可以讓程式碼更加簡潔,同時也告訴編譯器我們有意忽略索引值,不需要對它進行操作。

2.4 switch 敘述

switch 用於根據不同的情況執行不同的程式碼區塊。
它允許根據一個表達式的值(也被稱為「案例」)的不同值,有效地將執行轉移到程式碼的不同部分。在Go語言中,有兩種類型的 switch 陳述句:

  1. Expression Switch(表達式switch):這是最常見的 switch 類型。在這種情況下,switch 的表達式會被計算一次,然後根據該表達式的值選擇要執行的程式碼區域。每個 case 表達式會與 switch 表達式的值進行比較,並在找到匹配的 case 時執行相對應的程式碼。

  2. Type Switch(類型switch):這種 switch 用於檢查介面(interface)值的具體類型。它允許你根據interface值的具體類型執行不同的程式碼。這在處理interface時非常有用,因為interface可以容納不同類型的值,並且你可能需要根據實際的具體類型來執行不同的操作。

Expression Switch基本結構 :

switch optstatement; optexpression{
case expression1: Statement..
case expression2: Statement..
...
default: Statement..
}
  • optstatement 和 optexpression 在 Expression Switch 中都是可選的陳述句。

  • 如果同時存在 optstatement 和 optexpression,則它們之間需要使用分號(;)分隔。

  • 如果 switch 中不包含任何表達式,則編譯器會假定表達式為真(true)。

  • optstatement 中包含簡單的陳述句,例如變數聲明、增量或賦值陳述句、函數呼叫等等。

  • 如果在 optstatement 中存在變數,則該變數的作用域僅限於該 switch 陳述句內部。

  • 在 switch 陳述句中,case 和 default 陳述句不包含 break 陳述句。但你可以使用 break 和 fallthrough 陳述句,根據你的程式需要。

  • default 陳述句在 switch 陳述句中是可選的。

  • 一個 case 可以包含多個值,這些值之間用逗號(,)分隔。

  • 如果一個 case 不包含任何表達式,則編譯器會假定表達式為真(true)。
    (資料來源 : switch statement in go)

範例 :

switch day {
case "Monday":
    fmt.Println("It's Monday!")
case "Tuesday":
    fmt.Println("It's Tuesday!")
default:
    fmt.Println("It's some other day.")
}

Type Switch基本結構

switch optstatement; typeswitchexpression{
case typelist 1: Statement..
case typelist 2: Statement..
...
default: Statement..
}
//空介面,也就是可以儲存任何類型的值。
//因此,這個 x 變數可以容納任何數據類型的值,包括整數、字串、自定義結構等。
var x interface{} = 42

switch x.(type) {
case int:
    fmt.Println("x is an int")
case string:
    fmt.Println("x is a string")
default:
    fmt.Println("x is some other type")
}

這段程式碼將輸出 "x is an int"。

以上94基本流程控制的部分~~~~thx


上一篇
[Day03] Go in 30 - 變數與算符 Part02 運算子與指標
下一篇
[Day05] Go in 30 - 核心型別
系列文
Go in 3o30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言