iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
自我挑戰組

Go in 3o系列 第 5

[Day05] Go in 30 - 核心型別

  • 分享至 

  • xImage
  •  

一、前言

本篇介紹與整理 Go 語言 中型別的部分。

  • 布林值:true/false
  • 數字
  • 整數
  • 浮點數
  • 溢位和越界繞回
  • 大數值
  • 位元組(Byte)
  • 字串(String)
  • 字串與字串常值
  • Rune
  • nil 值

二、核心型別

2.1 布林值:true/false

布林值在 Go 中用來表示邏輯值,只有兩個可能的值:true(真)和 false(假)。它通常用於條件語句和邏輯運算符,例如 if 語句和 &&(與)和 ||(或)運算符。

2.2 數字

2.2.1 整數

整數型別用於表示整數值。在 Go 中,整數型別包括 int(依架構大小可變)、int8、int16、int32、int64(分別表示 8、16、32、64 位帶符號整數)以及 uint、uint8、uint16、uint32、uint64(分別表示無符號整數)。例如,int 型別的變數可以儲存整數值,如 42 或 -10。

** ps. rune 是 int32 的別稱,byte 是 uint8 的別稱。**

類型 儲存大小 範圍 範例值
int 依架構大小可變 通常為 32 位元或 64 位元 42, -10
int8 8 位元 -128 到 127 -128, 127
int16 16 位元 -32768 到 32767 -32768, 32767
int32 32 位元 -2147483648 到 2147483647 -2147483648, 2147483647
int64 64 位元 -9223372036854775808 到 9223372036854775807 -9223372036854775808, 922337203685477580
uint 依架構大小可變 通常為 32 位元或 64 位元 42, 100
uint8 8 位元 0 到 255 0, 255
uint16 16 位元 0 到 65535 0, 65535
uint32 32 位元 0 到 4294967295 0, 4294967295
uint64 64 位元 0 到 18446744073709551615 0, 18446744073709551615

範例:

package main

import "fmt"

func main() {
    var a int8 = 120
    var b int16 = 30000
    var c int32 = 2147483640
    var d int64 = 9223372036854775800

    fmt.Println(a) // 輸出:120
    fmt.Println(b) // 輸出:30000
    fmt.Println(c) // 輸出:2147483640
    fmt.Println(d) // 輸出:9223372036854775800
}

package main

import "fmt"

func main() {
    var m uint = 42
    var n uint8 = 255
    var p uint16 = 65535
    var q uint32 = 4294967295
    var r uint64 = 18446744073709551615

    fmt.Println(m) // 輸出:42
    fmt.Println(n) // 輸出:255
    fmt.Println(p) // 輸出:65535
    fmt.Println(q) //
}

注意事項

  • 這些型別的變數之間不允許互相賦值,不然會執行時會報錯。
    如下的程式碼會產生錯誤:invalid operation: a + b (mismatched types int8 and int32)
var a int8
var b int32
c:=a + b
  • 另外,儘管 int 的長度是 32 bit, 但 int 與 int32 並不可以互用。

補充整數使用:

確認型別
Go如果沒有宣告型別,預設為int,如果要檢查是什麼型別可以由 fmt.Printf 來Check他的型別。

func main() {
    fmt.Print("Hello World !")
    var num = 100
    fmt.Printf("num 型別是 : %T", num)
}

輸出結果 :

C:\Users\Ricky\_practice\goproject\src\go_code\project01\main>myhello.exe
Hello World !num 型別是 : int

確認某型別占用多少字元

func main() {
    var num2 int64 = 10
    // unsafe.Sizeof 可以返回num2所占用的字元數
    fmt.Printf("num2 型別是 : %T 且占用字元為 %d ", num2 , unsafe.Sizeof(num2))
}

輸出結果 :

num2 型別是 : int64 且占用字元為 8

2.2.2 浮點數

浮點數類型用於表示帶有小數部分的數字。在 Go 中,有兩個浮點數類型:float32 和 float64,分別表示 32 位元和 64 位元的浮點數。例如,float64 型別的變數可以儲存小數值,如 3.14 或 0.01。

範例:

package main

import "fmt"

func main() {
     // 使用 float64 宣告浮點數變數
     var x float64 = 3.14
     var y float64 = 0.01

     fmt.Println(x) // 輸出:3.14
     fmt.Println(y) // 輸出:0.01

     // 使用 float32 宣告浮點數變數
     var a float32 = 1.23456789
     var b float32 = 2.34567890

     fmt.Println(a) // 輸出:1.2345679
     fmt.Println(b) // 輸出:2.3456788(精度有限)
}

2.2.3溢位和越界繞回 overflow and 'wrap around'

在 Go 中,如果整數類型的值超出其範圍,它會發生溢位並"繞回"到該類型的最小值或最大值,而不會引發運行時錯誤。這意味著如果對整數進行超出其最大值或最小值的運算,結果可能不如預期。

範例:

package main

import "fmt"

func main() {
     var maxInt8 int8 = 127
     var minInt8 int8 = -128

     // 嘗試將 maxInt8 + 1,超出了 int8 的最大範圍
     result1 := maxInt8 + 1
     // 嘗試將 minInt8 - 1,超出了 int8 的最小範圍
     result2 := minInt8 - 1

     fmt.Println("maxInt8 + 1 =", result1) // 輸出:maxInt8 + 1 = -128
     fmt.Println("minInt8 - 1 =", result2) // 輸出:minInt8 - 1 = 127
}

在上述範例中,我們定義了一個int8型別的變數maxInt8,其值為127,以及int8型別的變數minInt8,其值為-128。 然後,我們嘗試分別對maxInt8加1和minInt8減1,超出了int8的範圍。

結果是,當超出int8的最大範圍時,它會從最小值-128開始繼續增加,而當超出最小範圍時,它會從最大值127開始繼續減少。 這種行為稱為"繞回",Go語言不會引發執行時期錯誤,而是根據類型的特性繼續執行操作。

這就是為什麼在處理整數時,特別是涉及邊界值的情況時,需要格外小心,以確保不會發生意外的溢出和繞回。 如果需要進行溢出檢查或處理,可以使用條件語句來檢查結果並採取適當的措施。

2.2.4 大數值處理(math/big套件)

在 Go 語言中,標準函式庫提供了一個名為 math/big 的套件,用於處理大數值,這些數值超出了標準整數和浮點數的範圍。 math/big 套件可讓我們執行高精度的算術運算。

範例:

// 創建大整數
x := new(big.Int)
y := big.NewInt(12345)

計算範例

package main

import (
	"fmt"
	"math/big" //導入 math/big 包
)

func main() {

// 創建大浮點數
f := new(big.Float).SetFloat64(3.14159265358979323846)

a := big.NewInt(100)
b := big.NewInt(200)

// 相加
c := new(big.Int)
c.Add(a, b)

// 相乘
d := new(big.Int)
d.Mul(a, b)

// 相除
e := new(big.Float)
e.Quo(f, new(big.Float).SetFloat64(2.0))

fmt.Println("大整數相加結果:", c)
fmt.Println("大整數相乘結果:", d)
fmt.Println("大浮點數相除結果:", e)
}

輸出結果 :
https://ithelp.ithome.com.tw/upload/images/20230920/20162693yRVzmHZE3Q.png

2.2.5 字節 (Byte)

在Go中,byte是uint8的別名,通常用來表示8位元的資料單元。 它通常用於處理二進位資料和位元組流。

package main

import "fmt"

func main() {
     // 宣告一個 byte 變數並賦值
     var b byte = 65 // ASCII碼中的大寫字母'A'

     fmt.Printf("b 的值:%d\n", b) // 輸出:b 的值:65
     fmt.Printf("b 的字元表示:%c\n", b) // 輸出:b 的字元表示:A

     // 建立一個 byte 切片
     byteArray := []byte{'H', 'e', 'l', 'l', 'o'}

     // 列印 byte 切片中的每個位元組
     fmt.Println("位元組切片:", byteArray) // 輸出:位元組切片: [72 101 108 108 111]

     // 將 byte 切片轉換為字串
     str := string(byteArray)
     fmt.Println("字串:", str) // 輸出:字串: Hello
}

3-4 字串 (String)

字串類型(string)用於表示文字資料。 字串是不可變的,這意味著一旦創建,就不能更改其內容。 您可以使用雙引號(" ")或反引號(`)來建立字串字面值。

字串宣告範例:

var hiThere string  // 宣告變數為字串的一般方法
var empty string = ""  // 宣告了一個字串變數,初始化為空字串

字串相關操作:

package main

import "fmt"

func main() {
     // 宣告一個字串變數並賦值
     str1 := "Hello, World!"
     fmt.Println("字串1:", str1)

     // 字串連接
     str2 := "Hello, "
     str3 := "World!"
     result := str2 + str3
     fmt.Println("字串連接:", result)

     // 字串長度
     length := len(str1)
     fmt.Println("字串長度:", length)

     // 存取字串中的字元(Unicode字元)
     char := str1[0]
     fmt.Printf("第一個字元: %c\n", char)
}

在上述範例中,我們示範了以下操作:

  • 建立字串變數並賦值。
  • 使用+運算子連接字串。
  • 使用len函數取得字串的長度。
  • 訪問字串中的字符,字串中的字符是Unicode字符

不可變動: (如果這樣更改的話會報錯 cannot assign to hello[0] )

var hello string = "hello"
hello[0] = 'H'

**那如果要更改呢~?
**

package main

import "fmt"

func main() {
    str := "hello"
    byteArray := []byte(str) //將字串轉byte陣列

    byteArray[0] = 'H' // 修改byte陣列的内容

    modifiedStr := string(byteArray) // 轉回字串

    fmt.Println(modifiedStr) // 輸出:Hello
}

3-4-1 字串常值

字串可以包含任何Unicode字符,並且支援各種字串操作,如連接、分割、索引等。 而字串常值是包含在雙引號內的文本,例如:"Hello, World!"。

package main

import "fmt"

func main() {
     // 字串常值範例
     str1 := "Hello, World!"
     str2 := "你好,世界!"
     str3 := "🌍🌎🌏"

     fmt.Println("字串常數1:", str1)
     fmt.Println("字串常數2:", str2)
     fmt.Println("字串常數3:", str3)
}

https://ithelp.ithome.com.tw/upload/images/20230920/20162693Jlmeg6o3Tp.png

3-4-2 Rune

rune是int32的別名,通常用於表示Unicode字元。 在Go中,字串是由一系列rune組成的,這使得Go非常適合處理多語言和國際化文字。

示範如何使用 rune 處理 Unicode 字串:

package main

import "fmt"

func main() {
     // 使用 rune 建立一個 Unicode 字符
     var r rune = '你'
     fmt.Printf("單一 rune: %c\n", r) // 輸出:單一 rune: 你

     // 建立一個包含多個 Unicode 字元的字串
     str := "Hello 世界"
     fmt.Println("完整字串:", str) // 輸出:完整字串: Hello 世界

     // 遍歷字串中的每個 rune
     for i, runeValue := range str {
         fmt.Printf("字元 %d: %c\n", i, runeValue)
     }
}

https://ithelp.ithome.com.tw/upload/images/20230920/20162693wbddG3yDOT.png

3-5 nil 值

在Go中,nil表示零值或空值,可以用於多種資料類型,如指標、切片、映射、通道和介面。 它表示變數未分配任何值或指向任何內容。

本篇介紹了 Go 語言中的一些核心型別,包括布林值、整數、浮點數、位元組、字串、Rune 和 nil 值,接下來會進入複合型別的部分。

參考資料:Go基礎


上一篇
[Day04] Go in 30 - 變數與算符 part03 常數、列舉、Scope,套一些流程控制
下一篇
[Day06] Go in 30 - 複合型別
系列文
Go in 3o30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言