Go言語(golang)のstruct
structの使い方を説明します。Tour of Goを参考にしています。
複数のデータ型をまとめて、ひとつの新しいデータ型を作成できるのがstructです。構造体とも呼ばれます。
Go言語(golang)のstructの使い方
Golangのstruct
は、関連する異なるデータ型をまとめ、新しい複合データ型を作成するための仕組みです。struct
はフィールドから構成され、これによって異なるデータ型の要素をひとまとめにすることができます。以下は基本的なstruct
の使用例です。
package main
import "fmt"
// Person structの定義
type Person struct {
FirstName string
LastName string
Age int
}
func main() {
// Person型の変数を作成
person1 := Person{
FirstName: "John",
LastName: "Doe",
Age: 30,
}
// フィールドへのアクセス
fmt.Println("First Name:", person1.FirstName)
fmt.Println("Last Name:", person1.LastName)
fmt.Println("Age:", person1.Age)
// フィールドの更新
person1.Age = 31
fmt.Println("Updated Age:", person1.Age)
}
結果
First Name: John
Last Name: Doe
Age: 30
Updated Age: 31
この例では、Person
という名前のstruct
がFirstName
、LastName
、Age
という3つのフィールドを持っています。これを使ってperson1
という変数を作成し、各フィールドにアクセスしています。
Golangのstruct
の特徴:
- フィールドの初期化:
Person
型の変数を作成する際、フィールドに初期値を指定することができます。また、初期化時に一部のフィールドだけを指定し、残りはゼロ値が設定されます。 - フィールドの更新: 作成した
struct
のフィールドは、後から更新することができます。 - メソッドの追加:
struct
にはメソッド(関数)を関連付けることも可能です。これにより、特定のデータ型に対する操作をカプセル化できます。
// メソッドの追加
func (p Person) FullName() string {
return p.FirstName + " " + p.LastName
}
// ...
// メソッドの呼び出し
fullName := person1.FullName()
fmt.Println("Full Name:", fullName)
struct
は、関連するデータをまとめ、プログラムの構造を効果的に表現するために使用されます。
structの使い所
struct
は、異なるデータ型の要素をまとめ、新しい複合データ型を作成するための有用な仕組みです。以下は、struct
の使いどころや一般的な利用例です。
データのまとめ
struct
は関連するデータをまとめるのに便利です。たとえば、ユーザーや商品の情報など、1つのエンティティに関連する異なる属性をまとめるのに使います。
type User struct {
ID int
Username string
Email string
// 他にも様々な属性がここに含まれる可能性がある
}
関数におけるパラメータのまとめ
複数の関連するパラメータを1つの引数として受け渡す場合、struct
を使用して関連するデータをまとめることができます。
type Point struct {
X, Y int
}
func move(p Point, dx, dy int) Point {
p.X += dx
p.Y += dy
return p
}
メソッドの追加
struct
には関数(メソッド)を関連付けることができます。これにより、特定のデータ型に対する操作をカプセル化し、よりオブジェクト指向的なアプローチを取ることができます。
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
JSONデータの表現
struct
はJSONデータの構造を表現するのにも適しています。JSONデータは一般的にキーと値のペアの集合であり、struct
はそのようなデータ構造を表現するのに適しています。
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Email string `json:"email"`
}
データベースとの対話
データベースとの対話においても、行やテーブルの構造を表現するためにstruct
が使用されます。ORM(Object-Relational Mapping)と組み合わせて、データベースとの対話を容易にします。
これらはstruct
を使用する典型的な場面の一部です。一般的に、関連する属性をグループ化してコードを整理し、可読性を向上させるために使われます。
structの注意点
ゼロ値
struct
を初期化しない場合、そのstruct
の各フィールドはゼロ値で初期化されます。これは、数値型の場合は0、文字列型の場合は空文字列などです。初期化が重要な場合は、適切に初期化するか、コンストラクタを使用するようにしましょう。
type Point struct {
X, Y int
}
// 初期化なしで宣言
var p Point
fmt.Println(p.X, p.Y) // ゼロ値が表示される
ポインタと値の挙動
struct
を関数に渡すとき、ポインタか値かによって挙動が異なります。ポインタを使ってstruct
を渡すと、関数内での変更が呼び出し元に影響しますが、値を使って渡すとコピーが作成され、関数内での変更が呼び出し元には反映されません。
type Person struct {
Name string
}
func modifyName(p Person) {
p.Name = "John"
}
func modifyNameWithPointer(p *Person) {
p.Name = "John"
}
// ...
person := Person{Name: "Alice"}
modifyName(person)
fmt.Println(person.Name) // Alice (変更が反映されない)
modifyNameWithPointer(&person)
fmt.Println(person.Name) // John (変更が反映される)
Immutableなフィールド
Golangのstruct
のフィールドは公開(大文字で始まる)または非公開(小文字で始まる)にできます。非公開フィールドは他のパッケージからアクセスできないため、変更不可(Immutable)と見なせます。一方で、公開フィールドには直接アクセスできるため、意図しない変更を防ぐためにはメソッドを経由してアクセスすることが望ましいです。
type Car struct {
model string // 非公開フィールド
}
func (c *Car) GetModel() string {
return c.model
}
// ...
car := Car{model: "Toyota"}
// 直接アクセスするとエラーになる
// fmt.Println(car.model) // エラー
// メソッドを経由してアクセス
fmt.Println(car.GetModel()) // Toyota
これらのポイントを考慮すると、より効果的かつ安全にstruct
を使用できます。特にデータの変更が制御されるべき場面では、ポインタを使ってstruct
を渡すことがより適しています。