anomalocaristan’s blog

JSやGo、設計などについて学んだことをメモしておくサイトです

Goの構造体

Angularとかやってればふんわり理解している構造体。
(っていうかAngularだとオブジェクト?)
いやAngularとかやってねーよ!て人の為に説明したいができないので、
とりあえず構造体とは何ぞやってところから復習。

構造体って?

プログラミング言語におけるデータ型の一つで、1つもしくは複数の値をまとめて格納できる型。

構造体 - Wikipedia

上記の通り、構造体は複数のプロパティをグルーピングできる。
JavaScriptだとオブジェクトに複数のプロパティを含めて、
そのプロパティに対して読み書きをすることができる。
厳密には違うのかもしれないが、Goでいう構造体とはJavaScriptのObject型と似たようなものだと思う。

構造体の宣言

Goの構造体は type [NAME] struct で宣言する。
また、構造体の呼び出し時は丸括弧じゃなくて波括弧

package main

import "fmt"

type Vertex struct {
  X int
  Y int
}

func main () {
  fmt.Println(Vertex{1,2})
  // => {1 2}
} 

構造体の初期化、フィールドへの代入と読み込み

特定のフィールドへの代入は、構造体を初期化してからじゃないとできない。
初期化をしていれば、再代入はできる。

package main

import "fmt"

type Vertex struct {
  X int
  Y int
}

func main () {
  fmt.Println(Vertex{1,2})
  // => {1 2}

  v := Vertex{0, 1} // 初期化方法1
  v.X = 5
  fmt.Println(v)
  // => {5 2}

  w := Vertex{} // 初期化方法2
  w.X= 1
  fmt.Println(w)
  // => {1 0}
} 

初期化方法1の場合、全フィールドに値が代入されていないとエラーになる。
初期化方法2の場合、代入されなかったフィールドはデフォルト値(今回なら0)になる。

フィールドを一定に保つ

構造体に定義していないフィールドに代入しようとするとエラーがでる。
なので、予期せぬフィールドが作成されることを防げる。
もちろん定義していないフィールドを読もうとしてもエラーになる。

package main

import "fmt"

type Vertex struct {
  X int
  Y int
}

func main () {
  Vertex.Z = 0
  fmt.Println(Vertex{1,2})
  // => Vertex.Z undefined (type Vertex has no method Z)
} 


参考:
構造体 - Wikipedia
A Tour of Go