これはSwiftのプログラミングスタイル、特にInt
とUInt
に関する質問です。
Swiftプログラミング言語ガイドは、変数が負でないことがわかっている場合でも、汎用の符号付き整数型Int
を使用することをプログラマーにアドバイスしています。From the guide :
UIntは、プラットフォームのネイティブのWordサイズと同じサイズの符号なし整数型が特に必要な場合にのみ使用してください。これが当てはまらない場合は、格納する値が負でないことがわかっている場合でも、Intが優先されます。型の安全性と型の推論で説明されているように、整数値にIntを一貫して使用すると、コードの相互運用性が向上し、異なる数値型間の変換が不要になり、整数型の推論に一致します。
ただし、UInt
は32ビットアーキテクチャでは32ビット符号なし、64ビットアーキテクチャでは64ビット符号なしになるため、Int
をUInt
よりも使用してもパフォーマンス上のメリットはありません。 。
対照的に、Swiftガイドは、後の例を示しています。
年齢= -3とする
assert(age> = 0、 "人の年齢はゼロ未満であってはなりません")
//これにより、年齢が> = 0ではないため、アサーションがトリガーされます
ここで、コードが次のように記述されている場合、runtimeの問題は、compile時にキャッチされる可能性があります。
let age:UInt = -3
// this causes a compiler error because -3 is negative
UInt
を使用すると、実行時ではなくコンパイル時に問題がキャッチされるケースは他にもたくさんあります(たとえば、コレクションにインデックスを付けるものなど)。
したがって、質問は、Swiftプログラミング言語ガイドサウンドのアドバイスであり、保存する値が非であることがわかっている場合でも、Int
を使用する利点があります。ネガティブ」は、UInt
を使用することの安全性の利点を上回ります。
追加注記:Swiftを数週間使用したことで、CocoaUInt
が必要です。たとえば、AVFoundation
フレームワークでは、「カウント」が必要な場所(サンプル/フレーム/チャネルなど)で符号なし整数を使用します。これらの変換Int
への値は、値がInt.max
より大きいという重大なバグにつながる可能性があります
UIntの使用は、あなたが思っているほど安全ではないと思います。あなたが指摘したように:
let age:UInt = -3
コンパイラエラーが発生します。私も試しました:
let myAge:Int = 1
let age:UInt = UInt(myAge) - 3
また、コンパイラエラーが発生しました。ただし、以下のシナリオ(実際のプログラムでははるかに一般的です)にはコンパイラエラーはありませんでしたが、実際にはEXC_BAD_INSTRUCTION
のランタイムエラーが発生しました。
func sub10(num: Int) -> UInt {
return UInt(num - 10) //Runtime error when num < 10
}
sub10(4)
と同様:
class A {
var aboveZero:UInt
init() { aboveZero = 1 }
}
let a = A()
a.aboveZero = a.aboveZero - 10 //Runtime error
これらが単純なInt
sであった場合、クラッシュする代わりに、条件をチェックするコードを追加できます。
if a.aboveZero > 0 {
//Do your thing
} else {
//Handle bad data
}
UInt
sを使用することに対する彼らのアドバイスを、暗黙的にラップされていないオプションを使用することに対する彼らのアドバイスと同等と見なすことさえあるかもしれません。ランタイムエラーを取得します(最も単純な場合を除く)。
それはあなたの質問で述べています。「整数値にIntを一貫して使用すると、コードの相互運用性が向上し、型の安全性と型の推論で説明されているように、異なる数値型間で変換する必要がなくなり、整数型の推論に一致します。」
これにより、UIntにIntを割り当てるなどの問題を回避できます。 UIntに割り当てられた負のInt値は、意図した負の値ではなく大きな値になります。両方のバイナリ表現は、タイプを区別しません。
また、どちらもクラスであり、一方は他方の子孫ではありません。構築されたクラスは、Intを受信してオーバーロードせずにUIntを受信できません。つまり、2つの間の変換は、フレームワークのほとんどがIntを受信するときに使用されるUIntの一般的なタスクです。 2つの間の変換も、重要なタスクになる可能性があります。
前の2つの段落では、「相互運用性」と「異なる数値タイプ間の変換」について説明しています。 UIntを使用しない場合に回避される問題。