Menu
Coddy logo textTech

型スイッチ

CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 18/68。

型アサーションは単一の型をチェックするのには適していますが、インターフェース変数に対して複数の可能性のある型を処理する必要があることがよくあります。ここで型スイッチが非常に便利になります。型スイッチを使用すると、具体的な型に基づいて異なるアクションを実行するためのクリーンな方法が提供されます。

型スイッチは、次の特別な構文を使用します: switch v := i.(type)。特定の型の代わりに (type) キーワードが使われていることに注目してください。変数 v には、各 case における具体的な型の実際の値が格納されます:

func describe(data interface{}) {
    switch v := data.(type) {
    case int:
        fmt.Printf("Integer: %d\n", v)
    case string:
        fmt.Printf("String: %s\n", v)
    case bool:
        fmt.Printf("Boolean: %t\n", v)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
}

各ケースにおいて、vは自動的に正しい型を持ちます。追加の型アサーションは必要ありません。これにより、特に1つの場所で複数の異なる型を処理する必要がある場合、if-else文で複数の型アサーションを連鎖させるよりも、型スイッチをはるかにクリーンに記述できます。

quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

challenge icon

チャレンジ

簡単

このチャレンジでは、通知システムで複数のデータ型を処理するために型スイッチ(type switch)を使用する練習をします。異なる種類の通知を処理し、その具体的な型に基づいて適切にフォーマットする関数を作成します。

2つの入力を受け取ります:

  • 通知タイプを表す文字列(例:"email""sms""push"、または "alert"
  • 通知の内容または値を表す文字列

あなたのタスクは以下の通りです:

  1. interface{} パラメータを受け取る processNotification という名前の関数を作成します。
  2. 入力された通知タイプに基づいて、内容を適切なGoの型に変換し、interface{} 変数に格納します:
    • "email" の場合:内容を文字列として使用します。
    • "sms" の場合:内容を整数(文字数を表す)に変換します。
    • "push" の場合:内容をブール値に変換します("enabled" の場合は true、それ以外は false)。
    • "alert" の場合:内容を float64(優先度レベルを表す)に変換します。
  3. 変換された値を使用して processNotification 関数を呼び出します。
  4. processNotification の内部で、型スイッチを使用して各型を処理し、適切なメッセージを出力します:
    • string の場合:"Email notification: [value]"
    • int の場合:"SMS notification with [value] characters"
    • bool の場合:"Push notifications: [value]"
    • float64 の場合:"Alert with priority: [value]"
    • その他の型の場合:"Unknown notification type"

文字列の変換には strconv パッケージを使用してください。ブール値の変換については、"enabled" の場合のみ true となるようにします。このチャレンジは、型スイッチがいかに単一の制御構造で複数の型を処理するクリーンな方法を提供し、各ケースで自動的に正しく型付けされた値を取得できるかを示しています。

チートシート

型スイッチ(type switch)を使用すると、構文 switch v := i.(type) を用いて、インターフェース変数の複数の可能な型を簡潔に処理できます:

func describe(data interface{}) {
    switch v := data.(type) {
    case int:
        fmt.Printf("Integer: %d\n", v)
    case string:
        fmt.Printf("String: %s\n", v)
    case bool:
        fmt.Printf("Boolean: %t\n", v)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
}

各ケースにおいて、変数 v は自動的に正しい具象型を持つため、追加の型アサーションを行う必要がなくなります。

自分で試してみよう

package main

import (
	"fmt"
	"strconv"
)

func main() {
	// 入力を読み込む
	var notificationType string
	var content string
	fmt.Scanln(&notificationType)
	fmt.Scanln(&content)
	
	// TODO: 以下にコードを記述してください
	// 1. interface{} 型のパラメータを受け取る processNotification 関数を作成する
	// 2. notificationType に基づいて content を適切な型に変換する
	// 3. 変換した値を使用して processNotification を呼び出す
	// 4. processNotification 内で型スイッチを使用して異なる型を処理する
	
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

論理とフローのすべてのレッスン