Swiftは型の安全性を重視しています。Swift言語全体は、安全性を考慮して設計されています。これはSwiftの特徴の1つであり、両手を広げて歓迎すべきものです。クリーンで読みやすいコードの開発を支援し、アプリケーションがクラッシュしないようにします。
Swiftのすべてのオプションは、?
記号で区切られています。?
オプションとして宣言する型の名前の後にを設定することにより、これを本質的にの前にある型としてではなく、オプションの型としてキャスト?
します。
注:変数または型Int
はと同じではありませんInt?
。これらは、互いに操作できない2つの異なるタイプです。
オプションの使用
var myString: String?
myString = "foobar"
これは、のタイプで作業しているという意味ではありませんString
。これは、String?
(String Optional、またはOptional String)のタイプで作業していることを意味します。実際、あなたがしようとするたびに
print(myString)
実行時に、デバッグコンソールはを出力しますOptional("foobar")
。" Optional()
"の部分は、この変数が実行時に値を持つ場合と持たない場合があることを示していますが、現在はたまたま文字列 "foobar"が含まれているだけです。この「Optional()
」の表示は、オプションの値の「アンラップ」と呼ばれる処理を行わない限り、残ります。
オプションをアンラップするということは、そのタイプを非オプションとしてキャストしていることを意味します。これにより、新しいタイプが生成され、そのオプション内に存在していた値が新しい非オプションタイプに割り当てられます。この方法では、コンパイラーによって確実な値を持つことが保証されているため、その変数に対して操作を実行できます。
条件付きアンラップは、オプションの値がであるかどうかをチェックしますnil
。でない場合nil
、値が割り当てられ、オプションではない定数にラップ解除される、新しく作成された定数変数があります。そして、そこから、if
ブロック内の非オプションを安全に使用できます。
注:条件付きでアンラップされた定数に、アンラップするオプション変数と同じ名前を付けることができます。
if let myString = myString {
print(myString)
// will print "foobar"
}
オプションの条件付きアンラップは、オプションの値にアクセスするための最もクリーンな方法です。オプションにnil値が含まれている場合、if letブロック内のすべてが実行されないためです。もちろん、他のifステートメントと同様に、elseブロックを含めることができます
if let myString = myString {
print(myString)
// will print "foobar"
}
else {
print("No value")
}
強制アンラップは、!
(「強打」)演算子として知られているものを使用することによって行われます。これは安全ではありませんが、コードをコンパイルできます。ただし、bang演算子を使用する場合は常に、強制的にアンラップする前に、変数に実際に確実な値が含まれていることを1000%確認する必要があります。
var myString: String?
myString = "foobar"
print(myString!)
上記は完全に有効なSwiftコードです。myString
「foobar」として設定された値を出力します。ユーザーはfoobar
コンソールに印刷されているのを見るでしょう、それはそれについてです。しかし、値が設定されていなかったとしましょう:
var myString: String?
print(myString!)
今、私たちは手に別の状況を持っています。Objective-Cとは異なり、オプションを強制的にアンラップしようとすると、オプションが設定されておらずnil
、オプションをアンラップしようとすると、アプリケーションの内部がクラッシュします。
タイプキャストを使用してアンラップします。すでに述べたように、あなたがunwrapping
オプションである間、実際には非オプションの型にキャストしていますが、非オプションを別の型にキャストすることもできます。例えば:
var something: Any?
コードのどこかに、変数something
に何らかの値が設定されます。たぶん私たちはジェネリックを使用しているのかもしれませんし、多分これを変更させる他のロジックが進行中なのかもしれません。したがって、コードの後半で使用したいのですsomething
が、それが別のタイプの場合でも別の方法で処理することができます。この場合、as
キーワードを使用してこれを決定する必要があります。
注:as
演算子は、Swiftでキャストを入力する方法です。
// Conditionally
if let thing = something as? Int {
print(thing) // 0
}
// Optionally
let thing = something as? Int
print(thing) // Optional(0)
// Forcibly
let thing = something as! Int
print(thing) // 0, if no exception is raised
2つのas
キーワードの違いに注意してください。前と同じように、オプションを強制的にアンラップしたときは、!
bang演算子を使用してアンラップしました。ここでは同じことを行いますが、単なる非オプションとしてキャストする代わりに、としてもキャストしますInt
。そして、それはとしてダウンキャストできなければなりませんInt
。そうでなければ、値がnil
アプリケーションであるときにbang演算子を使用するとクラッシュします。
また、これらの変数を何らかのソートまたは数学演算で使用するには、ラップ解除する必要があります。
たとえば、Swiftでは、同じ種類の有効な数値データタイプのみを相互に操作できます。を使用して型をキャストすると、as!
その変数がその型であることが確実であるかのように、その変数のダウンキャストが強制されるため、操作しても安全で、アプリケーションをクラッシュさせません。これは、変数が実際にキャスト先の型である限り問題ありません。そうでなければ、手に混乱が生じます。
それでも、withingをas!
使用すると、コードをコンパイルできます。とキャストすることas?
は別の話です。実際、は完全に異なるデータ型としてas?
宣言しますInt
。
今です Optional(0)
宿題を書こうとした場合
1 + Optional(1) = 2
あなたの数学の先生はおそらくあなたに「F」を与えたでしょう。Swiftも同様です。ただし、Swiftはグレードを付けるのではなく、まったくコンパイルしません。結局のところ、オプションは実際にはnilになる可能性があるためです。
安全第一キッズ。