型アサーション
基本的な型アサーション
- 基本的な型アサーション(型変換として使用可能):Xがインターフェース型で、Tが非インターフェース型の場合、アサーションが有効であるためには、TがインターフェースXを実装している必要があります
- TがXを実装している場合、変換は成功します。そうでない場合はpanicが発生し、プログラムが中断されます
- 構文
-
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 挨拶完了
*/
}