[解決済み] Swift言語におけるエクスクラメーションマークの意味とは?
質問内容
Swift プログラミング言語ガイド には、次のような例があります。
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
var john: Person?
var number73: Apartment?
john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)
//From Apple's “The Swift Programming Language” guide (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html)
そして、アパートを人に割り当てるとき、感嘆符を使って "インスタンスのラップを解除します"。
john!.apartment = number73
インスタンスのアンラップとはどういう意味ですか?なぜそれが必要なのですか?単に次のようにするのとどう違うのですか。
john.apartment = number73
私はSwift言語の超初心者です。 ただ、基本を押さえようとしているところです。
UPDATE
私が見逃していたパズルの大きなピース(回答には直接書かれていない-少なくともこれを書いている時点では)は、次のようなときです。
var john: Person?
ということではありません。
john
は、タイプ
Person
で、当初考えていたようにnil"になるかもしれません。単に私が誤解していたのは
Person
と
Person?
は全く別の型です。 それを把握すると、他のすべての
?
,
!
の狂気、そして以下の素晴らしい回答で、より一層理解することができました。
解決方法は?
<ブロッククオートインスタンスのアンラップとはどういう意味ですか?また、なぜそれが必要なのですか?
私が理解できる限りでは(私もこれは非常に新しいことです)...
この用語は、次のような意味を持っています。 Optional変数を光沢のある紙で包まれたプレゼントと考える。 .
Optional変数の値は、quot;wrap"されると、2つの値を持つenumになります(少しBooleanに似ています)。 この列挙型は、その変数が値を保持しているかどうかを記述します (
Some(T)
) か、そうでないか (
None
).
値がある場合は、変数をアンラップすることで取得できます(quot;unwrapping" を取得します)。
T
から
Some(T)
).
どのように
john!.apartment = number73
とは異なりjohn.apartment = number73
? (言い換え)
オプショナル変数の名前を書くと(例:テキスト
john
を使用せずに
!
) の場合、これは値そのもの (T) ではなく、 "wrapped" enum (Some/None) を指します。 つまり
john
のインスタンスではありません。
Person
であり、また
apartment
のメンバになります。
john.apartment
// 'Person?' does not have a member named 'apartment'
実際の
Person
の値は、さまざまな方法でアンラップすることができます。
-
"強制アンラップ"。
john!
(を与える)。Person
が存在する場合はその値を、nil の場合はランタイムエラーになります)。 -
"オプションのバインディング"。
if let p = john { println(p) }
(を実行します。println
値が存在する場合) -
"オプションのチェーニング"。
john?.learnAboutSwift()
(値が存在する場合、このメイクアップされたメソッドを実行します。)
nilの場合に何が起こるか、その可能性によって、これらの方法のいずれかを選択してアンラップするのでしょう。 この言語デザインは、nilケースを明示的に処理することを強制するので、(nilケースを処理することを忘れがちな)Obj-Cよりも安全性が向上しているのでしょう。
更新情報 :
感嘆符は、quot;Implicitly Unwrapped Optionals" を宣言する構文でも使用されています。
ここまでの例では
john
という変数が宣言されています。
var john:Person?
であり、Optionalです。 その変数の実際の値が欲しい場合は、上記の3つの方法のいずれかを使って、アンラップする必要があります。
として宣言されている場合
var john:Person!
この場合、変数は Implicitly Unwrapped Optional (Apple's book のこの見出しのセクションを参照) になります。 この種の変数は、値にアクセスする際にアンラップする必要はありません。
john
は、追加の構文なしで使用できます。 しかし、Appleの本にはこう書いてある。
暗黙的にアンラップされたオプショナルは、後の時点で変数がnilになる可能性がある場合には使用しないでください。変数のライフタイム中に nil 値をチェックする必要がある場合は、常に通常のオプショナル型を使用してください。
アップデート2 :
記事の"です。 Swiftの面白い機能 Mike Ashは、オプショナル型について、いくつかの動機を述べています。 とても分かりやすい文章で素晴らしいと思います。
アップデート3 :
に関するもう一つの有用な記事です。
暗黙のうちにアンラップされるオプション
はエクスクラメーションマークに使用します。
スウィフトとラストワンマイル
クリス・アダムソン著。 この記事では、AppleがObjective-Cフレームワークで使用する型にnilを含む可能性があることを宣言するために使用する実用的な手段であると説明されている。 ある型をオプションとして宣言する(そのためには
?
を使用)または暗黙のうちにアンラップされます。
!
は、安全性と利便性のトレードオフです。 この記事で紹介されている例では、Appleは型を暗黙的にアンラップすることを選択し、呼び出し側のコードをより便利にしましたが、安全性は低くなっています。
おそらくAppleは将来、自社のフレームワークを調べ上げ、暗黙のうちにアンラップされた("おそらく決してnil")パラメータの不確実性を取り除き、Objective-Cコードの正確な動作に基づいて、オプション("特定の(できれば文書で)状況で確かにnilとなり得る")または標準の非オプション("は決してnil")宣言でそれらを置き換えるかも知れません。
関連
-
[解決済み】「Fatal error: Unexpectedly found nil while unwrapping an Optional value "とはどういう意味ですか?
-
[解決済み] Swiftで辞書を繰り返し使用する
-
[解決済み] Xcode 8 シェルスクリプト呼び出しエラー
-
[解決済み] Swift における指数演算子
-
[解決済み] iPhone Simulator.appと一緒にXcodeも外付けハードディスクにインストールできますか?
-
[解決済み] メインスレッドチェッカー バックグラウンドスレッドで呼び出された UI API: -[UIApplication applicationState].
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swiftで乱数を生成する方法とは?
-
[解決済み】Swiftのオプション値とは何ですか?
-
[解決済み】UIViewControllerの最上位機種を取得する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Thread 1: signal SIGABRTエラーを解決するには?[クローズド]
-
[解決済み] Xcode 8 シェルスクリプト呼び出しエラー
-
[解決済み] このコンテキストで型検索を行う場合、「メソッド」は曖昧である、Alamofireのエラー
-
[解決済み] SwiftはPass By ValueかPass By Referenceか
-
[解決済み] SwiftでStringのサブストリングはどのように動作するか
-
[解決済み] テキストファイルからの文字列の読み込みと書き込み
-
[解決済み】swiftで変数のメモリアドレスを印刷する
-
[解決済み】プロパティのゲッターとセッター
-
[解決済み】swift言語におけるstructureとclassの比較
-
[解決済み】Swiftの`let`と`var`の違いは何ですか?