> For the complete documentation index, see [llms.txt](https://go.netdpi.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://go.netdpi.net/struct_interface/09.01-struct.md).

# 09.01-struct

要讓一個使程式變好，最簡單的方式是使用 struct，struct 是一種型別，包含多個有名稱的欄位。例如，我們可以用如下方式表示一個圓圈：

```go
type Circle struct {
    x float64
    y float64
    r float64
}
```

關鍵字 `type` 指出了一個新的型別，後面跟著型別的名稱（`Circle`），`struct` 關鍵字表示我們定義了一個 `struct` 型別，大括號裡面有一些欄位。每個欄位都有一個名稱與型別，如同函式那樣，我們也可以將相同型別的變數欄位放在一起：

```go
type Circle struct {
    x, y, r float64
}
```

#### 初始化 <a href="#toc-initialization" id="toc-initialization"></a>

有許多方式可以讓我們建立新的 Circle 型別之實體（instance）：

```go
var c Circle
```

如同其它的資料型別，這樣可以建立一個 Circle 區域變數，預設值為零。對於一個 `struct` 而言，設定為零表示將 struct 的每個欄位都設定為相對應的零值（`int` 型別設定為 0, `float` 型別設定為 0.0, `string` 型別設定為 "", 指標型別設定為 `nil` , …）。我們也可以使用 new 函式來建立：

```go
c := new(Circle)
```

這樣會為每個欄位配置記憶體空間，並將每個欄位設定為零，接著傳回一個指標（`*Circle`）。通常我們會比較想要為每個欄位設定一個值，有下列兩種方式：

```go
c := Circle{x: 0, y: 0, r: 5}
```

或是我們知道欄位名稱的定義順序，也可以直接賦值：

```go
c := Circle{0, 0, 5}
```

#### 欄位 <a href="#toc-fields" id="toc-fields"></a>

我們可以使用 `.` 運算符來存取這些欄位：

```go
fmt.Println(c.x, c.y, c.r)
c.x = 10
c.y = 5
```

再來修改 `circleArea` 函式，讓它可以使用一個 `Circle`：

```go
func circleArea(c Circle) float64 {
    return math.Pi * c.r*c.r
}
```

我們在 main 函式是這樣：

```go
c := Circle{0, 0, 5}
fmt.Println(circleArea(c))
```

要記得一件事情，就是 Go 語言一定會複製參數。如果我們修改 `circleArea` 函式中的欄位值，則不會更動到原本的變數。因此我們通常會以下列方式設計函式：

```go
func circleArea(c *Circle) float64 {
    return math.Pi * c.r*c.r
}
```

並修改 main 函式：

```go
c := Circle{0, 0, 5}
fmt.Println(circleArea(&c))
```

<br>
