Go/エラー
エラー 編集
エラー(Errors) -- 宣言済みの型であるerror
は次のように定義されています[1]。
type error interface { Error() string }
これは、エラー状態を表現するための従来のインターフェースで、nil値はエラーがないことを表します。例えば、ファイルからデータを読み取る関数が定義されているとします。
func Read(f *File, b []byte) (n int, err error)
ランタイム・パニック 編集
Goにおいて、配列の範囲外のインデックスを参照するなどの実行時エラーが発生した場合、ランタイム・パニック(Run-time panics)と呼ばれるエラーが発生します。このエラーは、ランタイムに発生するエラーであり、予期しない状況が発生したことを示しています。
ランタイム・パニックが発生した場合、プログラムは中断されます。この状況を回避するためには、プログラム内でエラー処理を実装する必要があります。ランタイム・パニックが発生した場合、組み込み関数 panic
が呼び出され、実装で定義されたインタフェース型runtime.Error
型のインタフェース値が生成されます。このエラーは、事前に宣言されたインタフェース型error
を満たします。
ランタイム・パニックは、Goのコンパイラによって検出できないエラーです。このため、ランタイム・パニックを回避するためには、コードを慎重にテストする必要があります。ランタイム・パニックが発生した場合、エラー値は不定であり、異なるランタイム・エラー条件を表すことがあります[2]。
package runtime type Error interface { error // そしておそらく他のメソッド }
システム面での注意点 編集
システム面での注意点(System considerations)[3]
パッケージ unsafe
編集
組込みパッケージ unsafe
は、コンパイラーに知られており、インポート・パス "unsafe"
でアクセスでき、型システムに違反する操作を含む低レベルのプログラミングのための機能を提供します。unsafe
を使用したパッケージは、手動で型安全性を吟味する必要があり、ポータブルではないかもしれません。パッケージは以下のインタフェースを提供します[4]。
package unsafe type ArbitraryType int // 任意のGo型の略語。実数型ではない。 type Pointer *ArbitraryType func Alignof(variable ArbitraryType) uintptr func Offsetof(selector ArbitraryType) uintptr func Sizeof(variable ArbitraryType) uintptr type IntegerType int // 整数型の略記で,実数型ではない func Add(ptr Pointer, len IntegerType) Pointer func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
Pointer
はポインター型ですが、Pointer
の値はdereferencedできません。基礎となる uintptr
型の任意のポインターまたは値は、基礎となる Pointer
型の型に変換することができ、その逆も可能です。Pointer
と uintptr
の間の変換の効果は、実装で定義されます。
var f float64 bits = *(*uint64)(unsafe.Pointer(&f)) type ptr unsafe.Pointer bits = *(*uint64)(ptr(&f)) var p ptr = nil
関数 Alignof
および Sizeof
は、任意の型の式 x
を受け取り、あたかも var v = x
で v
が宣言されたかのように、仮想変数 v
のアラインメントまたはサイズをそれぞれ返します。
Offsetof
関数は、s
または *s
で示される構造体のフィールド f
を示す(括弧で囲まれた)セレクタ s.f
を受け取り、構造体のアドレスに対するフィールドのオフセットをバイト単位で返します。
f
が埋め込みフィールドの場合は、構造体のフィールドを介してポインタの間接性なしに到達可能でなければなりません。
フィールド f
を持つ構造体 s
の場合。
uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
コンピューター・アーキテクチャーでは、メモリー・アドレスを整列(aligned)することが要求される場合があります。つまり、変数のアドレスは、変数の型の整列を表す係数の倍数でなければなりません。関数 Alignof
は、任意の型の変数を示す式を受け取り、(その型の)変数のアラインメントをバイト単位で返す。
変数 x
の場合。
uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0
Alignof
, Offsetof
, Sizeof
の呼び出しは、uintptr
型のコンパイル時定数式です。
関数 Add
は、len
を ptr
に追加し、更新されたポインター unsafe.Pointer(uintptr(ptr) + uintptr(len))
を返します。len
引数は、整数型または型付けされていない定数でなければなりません。定数の len
引数は int
型の値で表現できなければなりません。型付けされていない定数の場合は int
型になります。Pointer
の有効な使用法に関する規則も適用されます。
関数 Slice
は、基底となる配列が ptr
で始まり、長さと容量が len
であるスライスを返します。Slice(ptr, len)
は以下と同じです。
(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
ただし、特殊なケースとして、ptr
が nil
で len
が0の場合、Slice
は nil
を返します。
len
引数は整数型または型付けされていない定数でなければなりません。定数 len
の引数は非負で、int
型の値で表現できなければなりません。型付けされていない定数の場合は、int
型が与えられます。実行時に len
が負の値の場合、あるいは ptr
が nil
で len
が 0 でない場合、ランタイム・パニックが発生します。
サイズとアライメントの保証 編集
サイズとアライメントの保証(Size and alignment guarantees) -- 数値型では、以下のサイズが保証されています[5]。
型 バイト数 byte, uint8, int8 1 uint16, int16 2 uint32, int32, float32 4 uint64, int64, float64, complex64 8 complex128 16
以下のミニマムアライメント特性が保証されています。
- 任意の型の変数
x
に対して。unsafe.Alignof(x)
は最低でも1である。 - struct 型の変数
x
の場合。unsafe.Alignof(x)
は、x
の各フィールドf
の値unsafe.Alignof(x.f)
のうち最大のもので、少なくとも1である。 - 配列型の変数
x
の場合。unsafe.Alignof(x)
は、配列の要素型の変数のアラインメントと同じになります。
構造体や配列型は、ゼロより大きなサイズを持つフィールド(または要素)を含まない場合、サイズがゼロになります。2つの異なるゼロサイズの変数が、メモリ上で同じアドレスを持つことがあります。
脚註 編集
- ^ “Errors¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021) .
- ^ “Run time panics¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021) .
- ^ “System considerations¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021) .
- ^ “Package unsafe¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021) .
- ^ “Size and alignment guarantees¶”. The Go Programming Language Specification. The Go website. (Jul 26, 2021) .
参考文献 編集
- “Defer, Panic, and Recover - go.dev”. The Go Blog. The Go website. (2010-08-04) .