Programmingバックエンド開発者

Goにおける型付けと型チェックの仕組みを説明してください。型変換の種類は何があり、それぞれの違いは何ですか?

Hintsage AIアシスタントで面接を突破

回答

Go言語では、静的な厳密型付けが実装されています。つまり、変数の型はコンパイル時に知られており、コンパイラは互換性のない型に対する操作を許可しません。

型変換には2つの種類があります:

  1. 明示的な型変換 (Type Casting) – プログラマーが必要な型を明示的に指定する場合です。
  2. アサーション (type assertion) – インターフェースに対して特定の下位型を確認するために適用されます。

明示的な型変換の例:

var i int = 42 var f float64 = float64(i)

タイプアサーションの例:

var i interface{} = "hello" s, ok := i.(string) if ok { fmt.Println("String value:", s) } else { fmt.Println("iはstringではありません") }

型変換は、互換性のある基本型同士(int → float64, rune → int32, ただしstring → intは不可能)のみで可能です。

トリックな質問

interface{}はnil値を保持できるか?また、インターフェース型の変数が本当にnilであるかを正しく確認する方法は?

一般的な罠は、nil値を保持するインターフェースをnilと直接比較することです:

var err error = nil var i interface{} = err fmt.Println(i == nil) // trueを期待しますが、falseになります!

正しい方法:

インターフェース自体がnilであり、内包されている値もnilであることを確認します:

if i == nil || reflect.ValueOf(i).IsNil() { fmt.Println("iは実際にnilです") }

このトピックの繊細さを知らないことによる実際のエラーの例


物語

バックエンドプロジェクトで、開発者はさまざまなエラーをinterface{}を通じて処理しようとし、それらをnilと比較しました。その結果、エラーが正しく検出されず、隠れたバグやクライアントへのエラー返却の不正なロジックが発生しました。


物語

float64とintの間の明示的なキャストなしの移行は、サイレントデータロスを引き起こしました:値が丸められたり、不正確に移行されたりしました。Goのコンパイラは、そのような操作には明示的な変換を要求します。


物語

map[string]interface{}(例えば、JSONから)のインターフェース値のデシリアライズ時に、予期しないタイプのnumbers(float64)が発生し、追加のチェックなしでタイプアサーションを使用するとパニックが発生し、サービスがランタイムエラーでクラッシュしました。