はじめに
船井総研デジタルのoswです。業務でGo言語を使うことになったのでこれから学習していきます。その備忘録です。参考になる方がいらっしゃれば幸いです。
対象読者
- これからGo言語を学習する方
- 既に他の言語で基本構文を学習されている方
学習環境
学習環境は次のようになっています。この環境の構築メモは下記記事にまとめてあります。ご興味がある方はご参照ください。
- Windows 11 Home / 22H2
- VSCode / 1.72.2
- go version go1.19.2 windows/amd64
- git version 2.38.0.windows.1
前回までの学習
前回は インタフェース、型アサーション、型スイッチ を学習しました。
Stringerインタフェース
fmtパッケージが標準で持っているインタフェースのようです。githubでGoのソースを見てみると、このインタフェースは下記の実装になっており、 String() string
がただ1つ宣言されています。
このString()が何者か調べてみると、どうやらJavaでいうところのtoString()のようです。インタフェースを実装した型の変数を fmt.Println(変数)
のように渡すと、出力形式をString()で定義した通りにしてくれる、というものです。
以下でしか動作確認していませんが、少なくともこの2つはStringerインタフェースの実装にしたがって出力するようです。
- fmt.Println()
- fmt.Print()
type Stringer interface {
String() string
}
Stringerインタフェースを実装したもの、してないもので出力がどう変化するのか確認しました。結果は一目瞭然で、Stringerインタフェースを実装した側は出力形式が全く異なっています。
package main
import "fmt"
type Human struct {
Name string
Age int
}
type Person struct {
Name string
Age int
}
// Person型にStringerインタフェースを実装
func (person Person) String() string {
return fmt.Sprintf("名前は%sです。年齢は%d歳です。", person.Name, person.Age)
}
func main() {
fmt.Println("Stringer未実装")
human := Human {"田中太郎", 99}
fmt.Println(human)
fmt.Println("\nStringer実装済")
person := Person {"鈴木たろう", 50}
fmt.Println(person)
}
Stringer未実装
{田中太郎 99}
Stringer実装済
名前は鈴木たろうです。年齢は50歳です。
Errorインタフェース
Goには例外機構は備わっていないようです。その代わり(?)に戻り値とは別にエラーを示す値を返すことでエラー処理を行うようです。
どうやら、標準ライブラリなどはちょくちょく戻り値を2つ返すらしく、2つ目の戻り値がerrorインタフェース型になっているようです。error型のデータはCでいうところのerrnoと同じ感じでしょうか。
こちらもGoのソースを確認してみると、builtin.goにerrorインタフェースが定義されており、Error() string
が1つだけ宣言されていました。
こちらを実装して適切なエラー処理をしていくということですね。公式ドキュメントを確認してみると、エラー処理の起点となるerrorインタフェース型がnilならエラーではない、ということのようです。
こちらは完全に余談ですが、達人たちは例外を使わないようです。
type error interface {
Error() string
}
ErrorインタフェースもStringerインタフェース同様、fmt.PrintX(err)のように指定することで中身を吐いてくれるようです。
package main
import (
"fmt"
"time"
)
type TestError struct {
When time.Time
Msg string
}
// errorインタフェースの実装
func (err TestError) Error() string {
return fmt.Sprintf("%v: %v", err.Msg, err.When)
}
// errorインタフェース型の戻り値を返し、エラーと解釈させる
func causeError() error {
return TestError{
time.Now(),
"エラー発生!",
}
}
func main() {
// Errorインタフェース型はnilであればエラーは起きていない
if err := causeError(); err != nil {
fmt.Println(err)
}
}
エラー発生!: 2022-10-21 16:00:22.8513887 +0900 JST m=+0.002260301
fmtパッケージには fmt.Errorf()
なるものもあるようです。下記が参考になります。
おわりに
今回はここまでです。