構造体(struct)とは
Goにはクラスは存在しないらしく、その代わりに構造体を使用します。
名前(フィールド名)と型(int型やstring型など)を持つフィールドの集まりです。
メソッドや埋め込み(embedded)などといった機能も存在します。これらを含めると長くなってしまうので別の記事で紹介します。
なぜ使うのか
例えば、ユーザーのデータがあるとします。
この各ユーザーには共通して「名前」「性別」「年齢」のデータが必要です。
もしも構造体を使わなければ、以下の様に1つ1つ宣言する必要があります。
var name string
var sex string
var age int
しかし、これだとそれぞれ共通したユーザーデータなのに関連性が分かりません。(まとまりがない)
なので1つの関連性のあるデータなのだと分かりやすくする為に構造体を使用します。
type User struct {
Name string
Sex string
Age int
}
上記の様に構造体を使うことによって、「名前」「性別」「年齢」というユーザーデータがまとまって分かりやすくなりました。
(コードの書き方についてはすぐ下で説明します。)
構造体の使い方
次にGoでの構造体の使い方についてです。
定義方法、初期化方法、操作方法(値の変更)の3つに分けて説明したいと思います。
定義方法
先ほど、「名前(フィールド名)と型(int型やstring型など)を持つフィールドの集まりです。」と言いましたが、それがどういった意味なのかを見てみましょう。
構造体の定義にはtype
とstruct
を使用します。
type 構造体型の名前 struct {
フィールド名 型
}
type User struct {
Name string
Sex string
Age int
}
// 型が同じ場合、これでもOK
type User struct {
Name, Sex string
Age int
}
フィールド名の付け方には注意が必要
構造体を定義するときに注意して欲しいポイントとして、フィールド名の付け方があります。
上記の例ではフィールド名がName
やSex
、Age
の頭文字は大文字になっています。
これには理由があります。
実は構造体のフィールド名の頭文字を小文字にしてしまうと外部packageの外からアクセスできなくなるのです。
逆に大文字にすればpackageの外側からでもアクセスできる様になるというわけです。
どういうことかというと、例えば以下のようなディレクトリ構成があるとします。
|-----dir/sub.go
|
|-----main.go
小文字の場合
package dir
type User struct {
name, sex string
age int
}
package main
import (
"fmt"
"./mypkg"
)
func main() {
akihiro := User{Name: "彰宏", Sex: "男", Age: 23}
fmt.Println(akihiro)
}
実行結果はエラーが発生します。
大文字の場合
package dir
type User struct {
Name, Sex string
Age int
}
package main
import (
"fmt"
"./mypkg"
)
func main() {
akihiro := User{Name: "彰宏", Sex: "男", Age: 23}
fmt.Println(akihiro) // => {彰宏 男 23}
}
実行結果は{彰宏 男 23}
と正常に実行されます。
初期化方法
次に初期化方法です。
構造体については上記のUser
を使用します。
変数名 := 構造体型の名前{フィールド名: 任意の値}
// var akihiro User = User{Name: "彰宏", Sex: "男", Age: 23} と同じ
akihiro := User{Name: "彰宏", Sex: "男", Age: 23}
fmt.Println(akihiro) // => {彰宏 男 23}
他にもいくつかの宣言方法があるので紹介します。
akihiro := User{"彰宏","男", 23}
fmt.Println(akihiro) // => {彰宏 男 23}
var akihiro User
akihiro.Name = "彰宏"
akihiro.Sex = "男"
akihiro.Age = 23
fmt.Println(akihiro) // => {彰宏 男 23}
宣言時に値を何も取らなかった場合
var akihiro := User{}
fmt.Println(akihiro) // => { 0}
宣言時に値を何も取らなかった場合は、構造体のフィールドで定義した型の初期値が入ってきます。
つまり、Name
やSex
はstring型なので""
(空文字)、Age
はint型なので0
が入ってくるというわけです。
操作方法(値の変更)
初期化した構造体の値を変更するには、初期化した構造体を代入した変数
に.
でフィールド名
を繋げてあげればOKです。
akihiro := User{Name: "彰宏", Sex: "男", Age: 23}
fmt.Println(akihiro) // => {彰宏 男 23}
akihiro.Age = "18"
fmt.Println(akihiro) // => {彰宏 男 18}