gitkadoの気まぐれ日記

島根在住エンジニアが何かに興味を持ったらブログを更新します

Go備忘録 -struct周辺-

Go備忘録 -struct周辺-

  • Goにはクラスがない。代わりにstructを使用する
  • structはクラスのように関数定義できない(初めての経験)

Example

struct定義

type Person struct {
    FirstName string
    LastName string 
}

// 変数定義
// フィールド値なし
var person Person
person := Person{}
// フィールド値順
person := Person{"Taro", "Sato"}
// KeyValue指定
person := Person{FirstName: "Taro", LastName: "Sato"}

struct継承

import "fmt"

type Creature struct {
    Age int
    Sex string
}

func (c Creature) AgeAge() int {
    return c.Age * 2
}

type Person struct {
    // CreatureStructのフィールド値を埋め込み
    Creature
    FirstName string
    LastName  string
}

person := Person{
    Creature: Creature{
        Age: 1,
        Sex: "man",
    },
    FirstName: "Taro",
    LastName:  "Sato",
}

fmt.Println(person)
fmt.Println(person.Creature)
// PersonでAgeが定義されているようにアクセスできる
fmt.Println(person.Age)
// Creatureで定義した関数もPersonに継承される
fmt.Println(person.AgeAge())
// 実行結果
{{1 man} Taro Sato}
{1 man}
1
2

struct関数定義

import "fmt"

type Person struct {
    FirstName string
    LastName  string
}

func (p *Person) Name() string {
    return p.FirstName + " " + p.LastName
}

person := &Person{"Taro", "Yamada"}
fmt.Println(person.Name())
// 実行結果
Taro Yamada

NG

type Machine struct {
    Name string
}

func (m Machine) Name() string {
    return m.Name
}
// 実行結果
// (ERROR: Structで定義している属性と同名の関数は定義できない)
type Machine has both field and method named Name

interface(ダックタイピング)

import "fmt"

type Person struct {
    FirstName string
    LastName  string
}

func (p *Person) Name() string {
    return p.FirstName + " " + p.LastName
}

type Machine struct {
    Name string
}

type Named interface {
    Name() string
}

func printName(named Named) {
    fmt.Println(named.Name())
}

// ケース1
person := &Person{"Taro", "Yamada"}
printName(person)
// ケース2
machine := &Machine{"PC"}
printName(machine)
// 実行結果
// ケース1
Taro Yamada
// ケース2 (ERROR: MachineStructにName関数が定義されてない)
*Machine does not implement Named (missing Name method)