---
# System prepended metadata

title: 基礎資料型別

---

# 基礎資料型別

golang內建基礎型別包括：布林(bool)、數值、字串(string)。

## 布林

Go的布林型別為`bool`，值是 `true` 或`false`，預設為false。

以下三種方式皆可宣告

```go=
var enabled,disabled bool = false,true
var enabled,disabled = false,true
enabled,disabled := false,true
```

賦值
```go=
enabled = true
```

### 布林運算
Go語言內建的運算子有：

- 算術運算子
- 比較運算子
- 邏輯運算子
- 位元運算子
- 賦值運算子
- 其他運算子

可以對布林值使用 **邏輯運算子** 以及相等 `==` 或不等 `!=` 。

![](https://i.imgur.com/zDV5G8e.png)

布林型別範例：
```go=
truth := 3 <= 5
falsehood := 10 > 12

res1 := 10 > 15 && 4 == 5
res2 := 2*2 == 4 || 10%3 == 0

fmt.Println(truth, falsehood, res1, res2) // true false false true
```

## 數值

分為整數、浮點數、複數。

### 整數
整數型別有 **無符號** 和 **有符號** 兩種，Go同時支援 `int` 和 `unit`，這兩種型別的長度相同，但具體長度取決於不同編譯器的實現。

:::info
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
:::

![](https://i.imgur.com/bqbXkur.png)

**另外還有 byte(uint8的別名) 和 rune(int32的別名)**

:::success
Golang 沒有 `char` 資料型別。它使用 `byte` 和 `rune` 來表示字元值。

byte 資料型別用於表示 ASCII 字元，以及 rune 資料型別用於表示以 UTF-8 格式編碼的一組更廣泛的 Unicode 字元。
:::

### 浮點數

用於儲存帶小數部分的數字（如：3.1415926、123.45）。沒有 `float` 型別

:::info
float32 float64
:::

`float32` 在記憶體中佔用 32 位元，並以**單精度**浮點數格式儲存數值。
`float64` 在記憶體中佔用 64 位元，並以**雙精度**浮點數格式儲存數值。

浮點數的預設型別是 `float64`。

### 複數

:::info
complex64 complex128
:::

`complex64`：實部和虛部都是 `float32` 型別。
`complex128`：實部和虛部都是 `float64` 型別。

複數的預設型別是 `complex128`

#### 宣告複數

```go=
x := 3 + 2i //type complex128
fmt.Println(x) // (3+2i)
```

使用變數來建立複數需要使用到內建的 `complex` 函數：(複數的實部和虛部都必須是相同的浮點數型別)

```go=
a := 3.5
b := 6.2
c := complex(a,b)
fmt.Println(c) // (3.5+6.2i)
```

:::warning
不同型別的變數之間不允許互相賦值或操作，不然在編譯時會引起編譯器報錯。
:::

### 數值運算

可使用 **算術運算子、比較運算子、位元運算子、賦值運算子** 來做數值運算。

#### 算術運算子

設 A = 10 , B = 20

![](https://i.imgur.com/vKDCZMw.png)

#### 比較運算子

設 A = 10 , B = 20

![](https://i.imgur.com/SUEV0eD.png)

#### 位元運算子

包括 `&` (and), `|` (or), `^` (xor), `<<` (左移n位,就是乘以2的n次方), `>>` (右移n位,就是除以2的n次方)

![](https://i.imgur.com/C4cD5PM.png)

假設 p 為 20
p << 2 為 p * 2^2^ = 20 * 4 = 80
p >> 2 為 p / 2^2^ = 20 / 4 = 5

#### 賦值運算子

![](https://i.imgur.com/kVWxy9l.png)

## 字串

Go的字串都是採用UTF-8字符集編碼，字串由一對雙引號`" "`或反引號` `` `括起來定義。

```go=
var emptyStr string = "" //宣告字串變數 初始化為空字串

var hisName string 
hisName = "Jason" //賦值

/* 簡短宣告 */
myAge := "21" //雙引號
myAge := `21` //反引號
```

### 宣告多行字串

使用反引號` `` ` 括起的字串為Raw字串，程式碼怎麼寫就怎麼印，包括空格空行，沒有字元轉義。

```go=
str := `Hello
World`
fmt.Println(str)
```

```go=
Hello
World
```

在字串內使用空格

```go=
str2 := `Hello
        World`
fmt.Println(str2)
```
```go=
Hello
    World
```

### 字串連接

#### 字串與字串連接
使用 `+` 連接字串
```go=
fmt.Println("Hello " + "World")
```

#### 字串型別的變數之間連接
使用 `,` 隔開

```go=
str1 := "Hello"
str2 := "World"
fmt.Println(str1,str2) //Hello World , 字串型別變數連接會自動在兩個變數之間加入空格
```

#### 字串與其他變數型別連接
使用 `,` 隔開字串與變數

```go=
num := 3
fmt.Println("Number：",num) //Number： 3
```

### 字串分割

使用 `strings.Split(字串,"分割的字符")` 來分割字串。

```go=
str := "Hello, World"
str1 := strings.Split(str, ",")

fmt.Println(str1) // [Hello  World]
fmt.Println(str1[0]) // Hello
fmt.Println(str1[1]) // World
```

### 字串替換

使用 `strings.Replace(字串,"被替換的字符","替換的字符",-1)` 來替換字串內容。

```go=
str := "梅花梅花幾月開"
//字串替換, -1表示全部替換, 0表示不替換, 1表示替換第一個, 2表示替換第二個
str1 := strings.Replace(str, "梅花", "桃花", -1)
fmt.Println(str1) // 桃花桃花幾月開
```

leetcode有一題easy題可以使用字串替換快速解出

> **1108.Defanging an IP Address**
> 
> Given a valid (IPv4) IP address, return a defanged version of that IP address.
> A defanged IP address replaces every period “.” with “[.]”.
> 
> **Example 1:**
> 
> Input: address = “1.1.1.1”
> Output: “1[.]1[.]1[.]1”
> 
> **Example 2:**
> 
> Input: address = “255.100.50.0”
> Output: “255[.]100[.]50[.]0”

```go=
func defangIPaddr(address string) string {
    ip := strings.Replace(address, ".", "[.]", -1)
    return ip
}
```

### 字串擷取

使用 `str[start : end]` 來擷取字串。

```go=
str := "Hello, World"
str1 := str[3 : 8] //[3,8)
fmt.Println(str1) //lo, W
```

**擷取中文字串**

由於中文字不只是由一個byte組成，所以直接擷取中文字串可能會把一個中文字的編碼截成兩半，導致無法正確擷取內容。

```go=
name := "我是王小明"
fmt.Println("name[:4] = ",name[:4])　//name[:4] = 我?
```

先將其轉為`[]rune`，擷取後再轉回string。

```go=
nameRune := []rune(name)
fmt.Println("string(nameRune[:4]) = ",string(nameRune[:4])) //我是王小
```

## 補充

大寫字母開頭 ( 大駝峰 ) 的變數是可匯出的，也就是其它套件可以讀取的，是 **公有變數**；

小寫字母開頭 ( 小駝峰 ) 的就是不可匯出的，是 **私有變數**。

大寫字母開頭 ( 大駝峰 ) 的函式也是一樣，相當於 class 中的帶 public 關鍵詞的 **公有函式**；

小寫字母開頭 ( 小駝峰 ) 的就是有 private 關鍵詞的 **私有函式**。

```go=
// 公有函式，可以被外部package的代碼所使用
func Test() {
   //code
}

// 私有函式，package的内部可見
func test2() {
   //code
}
```