1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

入門プログラミングGo(構造体、インターフェイス)

Posted at

構造体の定義

    var curiosity struct {
        lat  float64
        long float64
    }
    // ファミリーの定義
	curiosity.lat = -4.44444
	curiosity.long = 133.333333

    //複合リテラルで定義も可能
    cr := curiosity{-4.44, 133.3333}

メソッドを使用した構造体の例

package main

import (
	"fmt"
)

type coordinate struct {
	d, m, s float64
	h       rune
}

func (c coordinate) decimal() float64 {
	sign := 1.0
	switch c.h {
	case 'S', 'W', 's', 'w':
		sign = -1
	}
	return sign * (c.d*c.m/60 + c.s/3600)
}
func main() {
	lat := coordinate{4, 35, 22.2, 'S'}
	long := coordinate{137, 26, 30.12, 'E'}
	fmt.Println(lat.decimal(), long.decimal())
}

コンストラクタを使用した構造体の初期化

package main

import (
	"fmt"
)

type coordinate struct {
	d, m, s float64
	h       rune
}

type location struct {
	lat, long float64
}

func (c coordinate) decimal() float64 {
	sign := 1.0
	switch c.h {
	case 'S', 'W', 's', 'w':
		sign = -1
	}
	return sign * (c.d*c.m/60 + c.s/3600)
}

func newLocation(lat, long coordinate) location {
	return location{lat.decimal(), long.decimal()}
}

func main() {
	curiosity := newLocation(coordinate{4, 35, 22.2, 'S'}, coordinate{137, 26, 30.12, 'E'})
	fmt.Println(curiosity)
}
  • コンストラクタの関数の名前はnewType or NewType
    • 外部へエクスポートするならNewType, 内部のみならnewType

(私見)構造体に対するメソッドの利点

  • オブジェクト指向:クラス内部で定義されたメソッドがクラスの各プロパティまたはメソッドを使用する
  • Golog:構造体をレシーバーで指定してその構造体全部を見られる(まとめが下手かもしれない。。。)

メソッドの転送

package main

import (
	"fmt"
)

type temperature struct {
	high, low celsius
}

type location struct {
	lat, long float64
}

type celsius float64

type report struct {
	sol         int
	temperature temperature
	location    location
}

func (t temperature) average() celsius {
	return (t.high + t.low) / 2
}

func (r report) average() celsius {
    // メソッドを転送してreportから直接average()を呼べるようにする
    // これにより、ロジックを丸々コピーする必要がない
	return r.temperature.average()
}

func main() {
	bradbury := location{-4.44, 133.33}
	t := temperature{high: -1.0, low: -78.0}
    // 各フィールドを指定して代入
	report := report{sol: 15, temperature: t, location: bradbury}
	fmt.Printf("%+v\n", report.temperature.high)
	fmt.Printf("%+v\n", report.temperature.low)
	fmt.Printf("%+v\n", report.average())
}

構造体の埋め込み

type report struct {
    sol int
    temperature // report に temperature 型を埋め込む
                // 埋め込み型と同じ名前のフィールドが生成される(この場合はtempareture)
    location
}

temperature型のメソッドが使用可能になる

インターフェース

  • それは何か=オブジェクト
  • それで何ができるか=インターフェース
    • 型が何を行えるかに焦点を絞っている

interface型

例えば

var t interface {
    talk() string
}

「引数を受け取らず、文字列を返すtalkという名前のメソッド」を指定している方ならば、このインターフェイスは満たされる。

package main

import (
	"fmt"
	"strings"
)

type martian struct{}

func (m martian) talk() string {
	return "nack nack"
}

type laser int

func (l laser) talk() string {
	return strings.Repeat("pew", int(l))
}

func main() {
	var talker interface {
		talk() string
	}
    
    // martian型はtalk()メソッドを持つ
	t = martian{}
	fmt.Println(t.talk())

	t = laser(3)
	fmt.Println(t.talk())
}

慣習的にinterface型には-erをつけるのが一般的

package main

import (
	"fmt"
	"strings"
)

type martian struct{}

func (m martian) talk() string {
	return "nack nack"
}

type laser int

func (l laser) talk() string {
	return strings.Repeat("pew", int(l))
}

type talker interface {
	talk() string
}

func shout(t talker) {
	louder := strings.ToUpper(t.talk())
	fmt.Println(louder)
}

func main() {

	shout(martian{})
	shout(laser(3))
}

インターフェースの条件を満たしていれば、適用可能
例えばlaserはtalk()メソッドを持っている→talkerインターフェイスの要件を満たす→shout()の引数になりうる

laser(3)だけだとわかりずらい
以下のように考える

a := laser(1)
fmt.Println(a)
shout(martian{})
shout(a)
  • aはlaser型で1とする
  • shout(a)によってa(laser型)はインターフェイスが満たされるのでshout()できる
  • インターフェイスの要件を満たせば関数に渡す引数の型を柔軟に選ぶことができる→インターフェイスの要件さえ満たせば、要件を満たす任意の構造体を関数の引数にとれる
  • インターフェイスは「君にはこれができますか?」という宣言
  • 構造体のメンバにインターフェイスの要件を満たすメソッドを持つものが存在すれば、その構造体のインスタンスはインターフェイスを引数にする関数を使用できる
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?