Go言語における型アサーション

型アサーション

基本的な型アサーション

  1. 基本的な型アサーション(型変換として使用可能):Xがインターフェース型で、Tが非インターフェース型の場合、アサーションが有効であるためには、TがインターフェースXを実装している必要があります
  2. TがXを実装している場合、変換は成功します。そうでない場合はpanicが発生し、プログラムが中断されます
  3. 構文

c := X.(T)


### 動的チェック(安全な)型アサーション

1. flagはbool型で、TがXを実装している場合、flagはtrueになります。そうでない場合はfalseになります。その他の動作は基本的な型アサーションと同じです。bool型のflagを使用して判断を行い、対応する操作を実装できます。結果が多い場合はswitch + typeを組み合わせて操作できます
2. なぜ安全と呼ばれるのでしょうか?Xの実際の型がアサーションした型Tでなくても、エラーで中断することなく、プログラムは続行されます**(アサーションが失敗した後でも、Tのメソッドが呼び出され、メソッドの例にジャンプします)**
3. 構文
4. ```
 c, flag := X.(T)
  • ただし注意:TはXを実装している必要があります。そうでない場合、このアサーション自体が無効であり、直接エラーが発生します

switch + typeによる判定

// 挨拶専用の関数を定義
func greet(s Greeter) {
	s.greet()
	switch s.(type) {
	case Japanese:
		jp := s.(Japanese)
		jp.performTraditionalDance()
	case Westerner:
		we := s.(Westerner)
		we.dance()
	}
	fmt.Println("挨拶完了")
}

コード例

package main
import "fmt"

// Greetingインターフェースを定義
type Greeter interface {
	greet()
}

// 日本人、西洋人の構造体を定義
type Japanese struct {
	name string
}

type Westerner struct {
	name string
}

// 日本人、西洋人にインターフェースを実装
func (j Japanese) greet() {
	fmt.Printf("%s: こんにちは\n", j.name)
}

func (w Westerner) greet() {
	fmt.Printf("%s: Hello\n", w.name)
}

// 例1: 基本的な型アサーション
func main() {
	w := Westerner{name: "John"}
	var g Greeter = g
	j := g.(Japanese) // panic発生: 型が異なるため、panic: interface conversion: main.Greeter is main.Westerner, not main.Japanese
	fmt.Println(j)
}

// 例2: 安全な型アサーション
func main() {
	w := Westerner{name: "John"}
	var g Greeter = g
	j, flag := g.(Japanese)
	fmt.Println(j, flag) // プログラムは正常に実行され: {} false と出力
}

メソッドの例

package main
import "fmt"

// Greetingインターフェースを定義
type Greeter interface {
	greet()
}

// 日本人、西洋人の構造体を定義
type Japanese struct {
	name string
}

type Westerner struct {
	name string
}

// 日本人、西洋人にインターフェースを実装
func (j Japanese) greet() {
	fmt.Printf("%s: こんにちは\n", j.name)
}

func (w Westerner) greet() {
	fmt.Printf("%s: Hello\n", w.name)
}

// 日本人、西洋人に固有のメソッドを追加
func (j Japanese) performTraditionalDance() {
	fmt.Printf("%s: 伝統的な踊りを披露\n", j.name)
}

func (w Westerner) dance() {
	fmt.Printf("%s: ダンスを踊る\n", w.name)
}

// 挨拶専用の関数を定義
func greet(s Greeter) {
	s.greet()
	// 固有のメソッドを呼び出す際に型アサーションを使用
	j, flag := s.(Japanese)
	j.performTraditionalDance()
	fmt.Println(j, flag, "挨拶完了")
}

func main() {
	jp := Japanese{name: "田中"}
	west := Westerner{name: "Mike"}
	greet(jp)
	greet(west) 
	/* 出力結果:
		田中: こんにちは
		田中: 伝統的な踊りを披露
		{田中} true 挨拶完了
		Mike: Hello
		Mike: ダンスを踊る
		{Mike} false 挨拶完了
	*/
}

タグ: Go言語 型アサーション インターフェース プログラミング

7月26日 22:29 投稿