SlideShare a Scribd company logo
インタフェースの
実装パターン
2014/08/09 (土)
@Go lang勉強会
自己紹介
上田拓也
KLab株式会社
仕事:
Webviewと戦う仕事
趣味:
Go言語, JS
twitter : @tenntenn
はじめに
● このプレゼンは以下の記事をまとめたものです
○ インタフェースの実装パターン
○ http://qiita.
com/tenntenn/items/eac962a49c56b2b15
ee8
● たぶん15分じゃ終わらないので,間に合わな
かったら,qiitaを見て下さい
アジェンダ
● typeで型を宣言する
● メソッド
● 基本的なインタフェースの実装
● 関数にインタフェース実装させる
● 構造体に埋め込んでインタフェースを実装する
● 埋め込みを使ったインタフェースの部分実装
● 埋め込みを使ったインタフェースの動的実装
typeで型を宣言する
構造体型とインタフェース型の宣言
// 構造体型の宣言
type Hoge struct {
// フィールドリスト
}
// インタフェース型の宣言
type Fuga interface {
// メソッドリスト
}
typeを型の宣言の文法
TypeDecl = "type" ( TypeSpec | "(" { TypeSpec
";" } ")" ) .
TypeSpec = identifier Type .
Type = TypeName | TypeLit | "(" Type ")" .
TypeName = identifier | QualifiedIdent .
TypeLit = ArrayType | StructType | PointerType
| FunctionType | InterfaceType
| SliceType | MapType | ChannelType .
typeを型の宣言の文法(ざっくり)
● type 識別子 型
○ 識別子:型名
○ 型
■ 型名
● int, string, fmt.Stringer
■ 型リテラル
■ (型)
既存の型に新しい名前をつける
● intに新しくHexという名前をつける
type Hex int
型リテラル
● 配列型  :[10]int
● 構造体型 :
struct { /* フィールドリスト */ }
● ポインタ型:*int
● 関数型  :function(s string) int
● インタフェース型:
interface { /* メソッドリスト */}
● スライス型:[]int
● マップ型 :map[string]int
● チャネル型:chan bool
関数型に名前をつけて型を宣言する
● net/httpパッケージのHandlerFuncは関数型にtype
で名前をつけたもの
type HandlerFunc func(wResponseWriter, r
*Request)
メソッド
メソッドの定義方法
// pはレシーバ
func (p *Person) String() string {
return fmt.Sprintf(
"%s %s (%d)",
p.FirstName,
p.LastName,
p.Age,
)
}
type Person struct {
FirstName string
LastName string
Age int
}
構造体型以外にもメソッドを設ける
● インタフェース型以外なら,どんな型でもレシー
バにできる
○ もちろん,型リテラルはダメ
type Hex int
func (h Hex) String() string {
return fmt.Sprintf(
"0x%x",
int(h),
)
}
関数にメソッドを持たせる
type HandlerFunc func(
w ResponseWriter,
r *Request,
)
func (f HandlerFunc) ServeHTTP(
w ResponseWriter,
r *Request,
) {
f(w, r)
}
基本的なインタフェースの実装
インタフェース型の宣言
type TypeName interface {
// メソッドリスト
Method1()
Method2()
}
インタフェースの実装
● メソッドリストのメソッドをすべて実装していれ
ば,インタフェースを実装したことになる
type Stringer {
String() string
}
// HexはStringerインタフェースを実装
type Hex int
func (h Hex) String() string {
return fmt.Sprintf("0x%x", int(h))
}
実際に,fmtパッケージで
定義されているインタ
フェース
インタフェースの実装
● int型の100をHex型にキャスト
● fmt.Stringer型の変数に代入して
いる
var stringer fmt.Stringer
stringer = Hex(100)
関数にインタフェース実装させる
関数にインタフェース実装させるには
● 関数の型リテラルにtypeで名前をつける
● 作った型にインタフェースで指定されているメ
ソッドを設ける
http.HandlerFuncの例
type HandlerFunc func(
w ResponseWriter,
r *Request,
)
func (f HandlerFunc) ServeHTTP(
w ResponseWriter,
r *Request,
) {
f(w, r)
}
http.HandlerFuncの例
● ServeHTTPメソッドを実装していれば,http.
Handlerインタフェースを実装したことになる
type Handler interface {
ServeHTTP(
w ResponseWriter,
r *Request,
)
}
http.HandlerFuncの例
● 関数をhttp.Hanlderとして振る舞わせる
f := http.HandlerFunc(func(
w http.ResponseWriter,
r *http.Request,
) {
fmt.Fprintf(w, "hello, world")
})
// 第1引数:pattern string
// 第2引数:handler http.Handler
http.Handle("/", f)
http.HandlerFuncの例
● 通常はhttp.HandleFuncを使う
● HandleFunc内では,関数をHandlerFunc型に
キャストして,http.Handleを呼んでいる
func HandleFunc(
pattern string,
handler func(ResponseWriter, *Request),
)
構造体に埋め込んでインタフェースを実装する
埋め込み
● 構造体には匿名フィールドとして,指定した型の
値を埋め込むことができる
● 埋め込んだ値のフィールドやメソッドはあたかも
埋め込み先のフィールドやメソッドのように利用
できる
埋め込みの例
type Name struct {
FirstName string
LastName string
}
func (n *Name) String() string {
return fmt.Sprintf("%s %s")
}
type Person struct {
*Name // *Name型の値を埋め込む
Age int
}
埋め込みの例
n := &Name{
FirstName: "Taro",
LastName: "Yamada",
}
p := &Person{
Name: n, // *Name型のnを埋め込む
Age: 20,
}
// nのメソッドをpのメソッドのように呼べる
fmt.Println(p.String())
埋め込みによるインタフェースの実装
● 埋め込んだ値がインタフェースを実装していた
場合,埋め込み先の構造体も,そのインタ
フェースを実装したことになる
// nがインタフェースを実装しているので,
// pもインタフェースを実装したことになる
var stringer fmt.Stringer = p
fmt.Println(stringer.String())
埋め込みを使ったインタフェースの部分実装
複数のメソッドを持つインタフェース
● インタフェースの宣言時に,メソッドリストに複数
のメソッドを指定できる
type Person interface {
Title() string
Name() string
}
一部のメソッドだけ実装させる
type person struct {
firstName string
lastName string
}
// Nameメソッドだけだと
// Personインタフェースは実装したことにならない
func (p *person) Name() string {
return fmt.Sprintf(
"%s %s", p.firstName, p.lastName
)
}
type Person interface {
Title() string
Name() string
}
残りは埋め込み先で実装させる
type female struct {
*person
}
func (f *female) Title() string {
return "Ms."
}
type male struct {
*person
}
func (m *male) Title() string {
return "Mr."
}
実装の切り分けは外部から隠蔽する
func NewPerson(
gender Gender,
firstName, lastName string,
) Person {
p := &person{firstName, lastName}
if gender == Femail {
return &femail{p}
}
return &male{p}
}
type Gender int
const (
Female = iota
Male
)
埋め込みを使ったインタフェースの動的実装
インタフェース型の埋め込み
● 型名がついていればどんな型でも匿名フィール
ドにして埋め込むことができる
type Hoge struct {
chan int // ダメ
[]int // ダメ
fmt.Stringer // OK
}
型リテラルは
ダメ
インタフェース型の埋め込み
func main() {
p := Person{
Stringer: nil,
FirstName: "Taro",
LastName: "Yamada",
Age: 20,
}
fmt.Println(p.Stringer) // nil
p.Stringer = ???
}
type Person struct {
fmt.Stringer
FirstName string
LastName string
Age int
}
fmt.Stringerインタフェースを実装していれば代入できる
埋め込む構造体をバインドする
● 埋め込んだインタフェース型の匿名フィールドに
インタフェースを実装した値を動的に代入できる
● 代入するインタフェースを実装した値は,埋め込
み先の構造体にアクセスできないと意味がない
○ 埋め込み先を参照できるクロージャにインタフェースを実
装させればよい
埋め込む構造体をバインドする
func BindStringer(
p *Person,
f func(p *Person) string) fmt.Stringer,
{
return StringerFunc(func() string {
return f(p)
})
} type StringerFunc func() string
func (sf StringerFunc) String() string {
return sf()
}
まとめ
● なんでもstructで型を作るのはGo言語っぽくな
い
○ typeとメソッドをちゃんとおさえる
● 埋め込みとインタフェースの実装をうまく使う
○ インタフェースの実装を埋め込む値に移譲するパターン
● The Go Programming Language Specificationを見なが
ら,黒魔術を考えるの楽しい
○ http://golang.org/ref/spec

More Related Content

PPTX
Prometheus入門から運用まで徹底解説
PPTX
Apache Avro vs Protocol Buffers
PDF
イミュータブルデータモデル(世代編)
PDF
外部キー制約に伴うロックの小話
PDF
RISC-V User level ISA
PDF
強いて言えば「集約どう実装するのかな、を考える」な話
PDF
Laravelを用いたゲームサーバーのチューニング
Prometheus入門から運用まで徹底解説
Apache Avro vs Protocol Buffers
イミュータブルデータモデル(世代編)
外部キー制約に伴うロックの小話
RISC-V User level ISA
強いて言えば「集約どう実装するのかな、を考える」な話
Laravelを用いたゲームサーバーのチューニング

What's hot (20)

PDF
webエンジニアのためのはじめてのredis
PDF
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
PDF
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
PDF
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
PPTX
Kafkaを活用するためのストリーム処理の基本
PDF
日本語テストメソッドについて
PDF
FridaによるAndroidアプリの動的解析とフッキングの基礎
PDF
TDDBC お題
PDF
PostgreSQLアンチパターン
PDF
ゴシッププロトコルによる冗長化と負荷分散の検証
PPTX
JIRA 업무 생산성 향상 및 프로젝트 관리
PDF
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
PDF
サーバPUSHざっくりまとめ
PDF
AWSのログ管理ベストプラクティス
PPTX
ゲームエンジニアのためのデータベース設計
PDF
ライブラリ作成のすゝめ - 事例から見る個人OSS開発の効能
PDF
Dockerからcontainerdへの移行
PDF
実環境にTerraform導入したら驚いた
PDF
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
PDF
gRPC入門
webエンジニアのためのはじめてのredis
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Dockerの期待と現実~Docker都市伝説はなぜ生まれるのか~
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
Kafkaを活用するためのストリーム処理の基本
日本語テストメソッドについて
FridaによるAndroidアプリの動的解析とフッキングの基礎
TDDBC お題
PostgreSQLアンチパターン
ゴシッププロトコルによる冗長化と負荷分散の検証
JIRA 업무 생산성 향상 및 프로젝트 관리
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
サーバPUSHざっくりまとめ
AWSのログ管理ベストプラクティス
ゲームエンジニアのためのデータベース設計
ライブラリ作成のすゝめ - 事例から見る個人OSS開発の効能
Dockerからcontainerdへの移行
実環境にTerraform導入したら驚いた
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
gRPC入門
Ad

Viewers also liked (20)

PDF
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会
PDF
Goroutineと channelから はじめるgo言語
PDF
Goとテスト
PDF
Go入門
PDF
HighBatch
PDF
Eureka go 2015_12_12
PDF
alphawing meets heroku
PDF
らくちん Go言語
PDF
Golang, make and robotics #gocon
PDF
cli.go と cli-init で高速にコマンドラインツールを開発する / The command-line tool developed at hi...
KEY
Chrome osとgo言語からgoogleの今後を妄想してみる
PDF
Go言語と過ごした一週間
PPTX
Github第8章
PPTX
Go+revel
PDF
Goを知る
PDF
Introduction to Vim plugins developed by non-Japanese Vimmer (Japanese version)
PDF
Dockerぐらし!
PDF
勉強会への一歩を踏み出すために
PDF
2015/02/21 GDG神戸 Go on Android ハンズオン&もくもく会
PPTX
マイクロサービスにおけるクエリー言語について
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会
Goroutineと channelから はじめるgo言語
Goとテスト
Go入門
HighBatch
Eureka go 2015_12_12
alphawing meets heroku
らくちん Go言語
Golang, make and robotics #gocon
cli.go と cli-init で高速にコマンドラインツールを開発する / The command-line tool developed at hi...
Chrome osとgo言語からgoogleの今後を妄想してみる
Go言語と過ごした一週間
Github第8章
Go+revel
Goを知る
Introduction to Vim plugins developed by non-Japanese Vimmer (Japanese version)
Dockerぐらし!
勉強会への一歩を踏み出すために
2015/02/21 GDG神戸 Go on Android ハンズオン&もくもく会
マイクロサービスにおけるクエリー言語について
Ad

Similar to インタフェースの実装パターン (20)

PDF
エキスパートGo
PDF
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
PDF
TechDo Goハンズオン#3
PDF
ジェネリック関数の呼び出され方 #cocoa_kansai
PDF
TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...
PDF
マスターオブゴールーチンアンドチャネル スタートGo #1
PDF
マスター・オブ・Reflectパッケージ
PDF
メルカリ・ソウゾウでは どうGoを活用しているのか?
PDF
interface の中身
PDF
Goの文法の実例と解説
PDF
JSX / Haxe / TypeScript
PPTX
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
PDF
ECMAScript没proposal追悼式
PPT
PDF
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
KEY
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
PPTX
flow による型のある世界入門
PDF
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
PPTX
大人のお型付け
PPTX
Javascriptのデザインパターン【勉強会資料】
エキスパートGo
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
TechDo Goハンズオン#3
ジェネリック関数の呼び出され方 #cocoa_kansai
TypeScript ファースト ステップ (v.0.9 対応版) ~ Any browser. Any host. Any OS. Open Sourc...
マスターオブゴールーチンアンドチャネル スタートGo #1
マスター・オブ・Reflectパッケージ
メルカリ・ソウゾウでは どうGoを活用しているのか?
interface の中身
Goの文法の実例と解説
JSX / Haxe / TypeScript
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
ECMAScript没proposal追悼式
Visual Studio 2012 Web 開発 ~ One ASP.NET から TypeScript まで ~
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
flow による型のある世界入門
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
大人のお型付け
Javascriptのデザインパターン【勉強会資料】

More from Takuya Ueda (20)

PDF
Goにおけるバージョン管理の必要性 − vgoについて −
PDF
WebAssembly with Go
PDF
GAE/Goとsyncパッケージ
PDF
静的解析を使った開発ツールの開発
PDF
そうだ、Goを始めよう
PDF
マスター・オブ・goパッケージ
PDF
メルカリ カウルのマスタデータの更新
PDF
Go1.8 for Google App Engine
PDF
Go Friday 傑作選
PDF
GoによるiOSアプリの開発
PDF
Static Analysis in Go
PDF
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
PDF
Go静的解析ハンズオン
PDF
Goにおける静的解析と製品開発への応用
PDF
オススメの標準・準標準パッケージ20選
PDF
Gopher Fest 2017参加レポート
PDF
Google Assistant関係のセッションまとめ
PDF
Cloud functionsの紹介
PDF
goパッケージで型情報を用いたソースコード検索を実現する
PDF
Cloud Functionsの紹介
Goにおけるバージョン管理の必要性 − vgoについて −
WebAssembly with Go
GAE/Goとsyncパッケージ
静的解析を使った開発ツールの開発
そうだ、Goを始めよう
マスター・オブ・goパッケージ
メルカリ カウルのマスタデータの更新
Go1.8 for Google App Engine
Go Friday 傑作選
GoによるiOSアプリの開発
Static Analysis in Go
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
Go静的解析ハンズオン
Goにおける静的解析と製品開発への応用
オススメの標準・準標準パッケージ20選
Gopher Fest 2017参加レポート
Google Assistant関係のセッションまとめ
Cloud functionsの紹介
goパッケージで型情報を用いたソースコード検索を実現する
Cloud Functionsの紹介

インタフェースの実装パターン