4
2

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言語入門 学習メモ 9 Stringerインタフェース、Errorインタフェース

Last updated at Posted at 2022-10-21

はじめに

船井総研デジタルの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()
print.go
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ならエラーではない、ということのようです。

こちらは完全に余談ですが、達人たちは例外を使わないようです。

builtin.go
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() なるものもあるようです。下記が参考になります。

おわりに

今回はここまでです。

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?