Swift言語で感嘆符はどういう意味ですか?


518

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言語に非常に慣れていません。基本を理解しようとしています。


更新:
私が行方不明だったパズルの大きな部分(答えに直接述べられていません-少なくともこれを書いている時点ではありません)は、次のことをするときです:

var john: Person?

私が最初に思ったように、それjohnは「タイプでPersonあり、それはnilかもしれない」という意味ではありません。私は単にそれを誤解してPersonおりPerson?、完全に別のタイプです。それを理解すると、他のすべて?!狂気、および以下の素晴らしい答えは、はるかに理解しやすくなりました。

回答:


530

「インスタンスをアンラップする」とはどういう意味ですか?なぜ必要なのですか?

私ができる限り(これも私にとって非常に新しいです)...

「ラップされた」という用語は、オプションの変数を光沢のある紙に包まれたプレゼントとして考える必要があることを意味します

「ラップ」されている場合、省略可能な変数の値は、2つの可能な値(ブール値に少し似ている)を持つ列挙型です。この列挙型は、変数が値を保持するか(Some(T))、保持しないか(None)を示します。

値がある場合は、変数を「アンラップ」することで取得できます(Tfromを取得Some(T))。

どうjohn!.apartment = number73違うのjohn.apartment = number73?(言い換え)

オプション変数の名前(たとえばjohn、なしのtext !)を記述する場合、これは値自体(T)ではなく、「ラップされた」列挙型(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の場合に何が起こるか、そしてその可能性に応じて、アンラップする方法の1つを選択したと思います。この言語の設計により、nilケースは明示的に処理されるように強制されます。これにより、Obj-C(nilケースの処理を忘れがちな場合)よりも安全性が向上すると思います。

更新

感嘆符は、「暗黙的にアンラップされたオプション」を宣言する構文でも使用されます。

これまでの例では、john変数はとして宣言されておりvar john:Person?、オプションです。その変数の実際の値が必要な場合は、上記の3つの方法のいずれかを使用して、変数をアンラップする必要があります。

var john:Person!代わりに宣言されている場合、変数はImplicitly Unwrapped Optionalになります(Appleの本のこの見出しのセクションを参照)。値にアクセスするときにこの種の変数をアンラップする必要はなく、john追加の構文なしで使用できます。しかしAppleの本はこう言っている:

後で変数がnilになる可能性がある場合は、暗黙的にアンラップされたオプションを使用しないでください。変数の有効期間中にnil値を確認する必要がある場合は、常に通常のオプションの型を使用してください。

アップデート2

Mike Ash の記事「Interesting Swift Features」は、オプションのタイプにいくつかの動機を与えています。素晴らしい、はっきりした文章だと思います。

アップデート3

感嘆符の暗黙的にアンラップされたオプションの使用に関する別の有用な記事:Chris Adamsonによる「Swift and the Last Mile」。この記事では、これは、Objective-Cフレームワークで使用される、nilを含む可能性のある型を宣言するために使用されるAppleによる実用的な方法であることを説明しています。型をオプション(を使用?)または暗黙的にアンラップ(を使用)として宣言すること!は、「安全性と利便性の間のトレードオフ」です。記事の例では、Appleは型を暗黙的にアンラップするものとして宣言することを選択しているため、呼び出しコードはより便利になりますが、安全性は低下します。

おそらく、Appleは将来的にフレームワークをくまなく調べ、暗黙的にアンラップされた(おそらくnilでない)パラメータの不確実性を取り除き、それらをオプション(「確かにnilである可能性が高い[うまくいけば、文書化されている!]状況)または標準の非-optional( "is never nil")宣言。Objective-Cコードの正確な動作に基づいています。


この説明はわかりません。!なしでコードを実行すると、それでも実際の値が返されます。多分!スピードのためですか?
リチャードワシントン

OK。したがって、ドキュメントは!確実に解くことができるとき。しかし、それなしで(リストの4番目のオプション-暗黙的なアンラップ)、最初にチェックしなくても、コードを正常に実行できます。値を返すか、nilの場合はnilを返します。しかし、それがnilでないことが確実にわかっている場合は、!......を使用してください。
リチャードワシントン

2
こんにちは@RichardWashington-私は私の回答に更新を追加しました。
アシュリー

Update 3はまさに私が探しているものです。それを読む前に、私は彼らがNSURLCredentialのようなものを返したときにAppleが嘘をついていると思った!実際にはnilになる可能性があります。
Golden Thumb 14

素晴らしい回答をありがとう@Ashley。この回答といくつかのAppleの迅速なコードの例を読んだ後、安全と生産性の間のこのトレードオフでは、通常、より安全な側にいることが最善であるように私には本当に思えます。私が見つけた注目すべき例外は、AppleがUI要素の強制アンラップを使用する場合です。これは、最初に、UI要素はストーリーボードを含む場合、通常はオプションです(プログラムで値が割り当てられていないため)、次に、ほとんどの場合それらを含むビューコントローラーがnilでない限り、nilを使用しないでください。
Mihir 2014

127

ここに私が違いがあると思います:

var john: Person?

ジョンは無にできる

john?.apartment = number73

コンパイラーはこの行を次のように解釈します。

if john != nil {
    john.apartment = number73
}

ながら

john!.apartment = number73

コンパイラーはこの行を単純に解釈します。

john.apartment = number73

したがって、!ifステートメントがラップ解除され、より高速に実行されますが、johnがnilの場合、ランタイムエラーが発生します。

したがって、ここでラップするとは、メモリラップであることを意味するのではなく、コードラップであることを意味します。この場合は、ifステートメントでラップされます。また、Appleは実行時のパフォーマンスに細心の注意を払っているので、可能な限り最高のパフォーマンスでアプリを実行します。

更新:

Stackoverflowでそれから最高の評判を得たので、4年後にこの回答に戻ります:)そのときのラップ解除の意味を少し誤解しました。4年経った今、ここでアンラップすることの意味は、元のコンパクトな形式からコードを拡張することだと思います。また、定義によってnilであるかどうかは不明なので、オブジェクトのあいまいさを取り除くことも意味します。上記のアシュリーの答えと同じように、何も含まれない可能性のあるプレゼントと考えてください。しかし、アンラッピングはコードのアンラッピングであり、列挙型を使用するメモリベースのアンラッピングではないとまだ思います。


9
私の遊び場でjohn.apartment = number73がコンパイルされない場合、john?.apartment = number73を指定する必要があります
Chuck Pinkert

2
@ChuckPinkertは正しいです。4行目をjohn?.apartment = number73に編集する必要がありますが、いい答えです!
Bruce

john.apartment = number73でエラーが発生します:オプションタイプの値「Person?」ラップされていません:「!」を使用するつもりでしたか または '?'?
スパイダーマン2015年

4
アンラップは、パフォーマンスに影響を与えません。「nilチェック」は実行時にも実行する必要があります。唯一の違いは、オプションに値が存在しない場合にランタイムエラーがスローされることです。
マディディエ2016年

67

TL; DR

Swift言語で感嘆符はどういう意味ですか?

感嘆符は効果的に次のように述べています。使ってください。」これは、オプションの値の強制アンラップと呼ばれます。

let possibleString: String? = "An optional string."
print(possibleString!) // requires an exclamation mark to access its value
// prints "An optional string."

let assumedString: String! = "An implicitly unwrapped optional string."
print(assumedString)  // no exclamation mark is needed to access its value
// prints "An implicitly unwrapped optional string."

ソース:https : //developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_399


11
私は今が起こっている理解しているので、あなたの答えは素晴らしいです。私が理解していないのは、暗黙的にアンラップされたオプションが存在する理由です。通常の文字列型ではなく、暗黙的にアンラップされたオプションの文字列として定義されたものを作成するのはなぜですか?その後の使用法は同じです。何が欠けていますか?
pachun

これはもう本当ではないようです。Swift 5のreplでは、実行するlet f: String! = "hello"print(f)、出力はのOptional("hello")代わりにになり"hello"ます。
numbermaniac

37

johnがオプションの変数である場合(このように宣言されています)

var john: Person?

その場合、johnが値を持たない可能性があります(ObjC用語では、nil値)

感嘆符は基本的にコンパイラに「これには値があることを知っているので、テストする必要がない」と伝えます。使用したくない場合は、条件付きでテストできます。

if let otherPerson = john {
    otherPerson.apartment = number73
}

この内部は、johnに値がある場合にのみ評価されます。


4
応答をありがとう、感嘆符がを言っているの理解しました。なぜ私はまだ頭を抱えているのです ...あなたはそれがコンパイラーに伝えていると言っていますそれ"。コンパイラがテストを行わない場合、何を購入しますか?感嘆符がないと、コンパイラーはエラーをスローしますか(まだ、Swiftをテストできる環境がありません)。それは !すべてのオプション変数に100%必要ですか?もしそうなら、なぜそれを欠けているのではなく、なぜAppleはそれを気にしなかったのか!「私はこれに価値があることを知っています、あなたはそれをテストする必要はありません」?
Troy

「コンパイラはエラーをスローしますか」-いいえ、期待どおりに値を返しても問題なく動作します。わかりません。それは !あなたが多分確信しているときだけ速度のために?
リチャードワシントン

実際、後のドキュメントでは、以下の例を使用して、暗黙的にアンラップされたオプションについて説明 “let possibleString: String? = "An optional string." println(possibleString!) // requires an exclamation mark to access its value // prints "An optional string.” しています。ここで何か奇妙に思われる。
リチャードワシントン

3
@RichardWashington正当な理由で混乱しています!ドキュメントの例はいくつかのものを省いており、printlnを使用するだけなので誤解を招く可能性があります。どうやら、オプションのアンラップが必要ないインスタンスが少なくともいくつかあります。1つは、printlnを使用する場合です。もう1つは、文字列補間を使用する場合です。それで、おそらくprintlnと文字列補間が隠れているのでしょうか?多分誰かがこれについてもっと洞察を持っているでしょう。Xcode6 Betaのヘッダー定義を調べても、この魔法については何もわかりませんでした。
mbeaty 2014年

はい、私はそれを取得John?し、John二つの異なる種類があります。1つはタイプOptional Personで、もう1つはタイプPersonです。Personを取得する前に、オプションのPersonをラップ解除する必要があります。しかし、あなたが言うように、これは少なくともこれらの状況では実際には何もしなくても起こるようです。これは!冗長。を除いて!常にオプションですが、コンパイル時エラーをキャッチするために推奨されることです。vars / letsを特定のタイプに割り当てるようなものは明示的にlet John: Person = ...することもできますが、推論することもできますlet John = ...
リチャードワシントン

27

他の有用であるがより詳細な中心の回答に追加するいくつかの全体像の視点:

Swiftでは、感嘆符はいくつかのコンテキストで表示されます。

  • 強制アンラップ: let name = nameLabel!.text
  • 暗黙的にアンラップされたオプション: var logo: UIImageView!
  • 強制鋳造: logo.image = thing as! UIImage
  • 未処理の例外: try! NSJSONSerialization.JSONObjectWithData(data, [])

これらはすべて、異なる意味を持つ異なる言語構成要素ですが、すべてに3つの重要な共通点があります。

1.感嘆符はSwiftのコンパイル時の安全性チェックを回避します。

使うとき !スウィフトに、あなたは基本的に、言っている「ねえ、コンパイラ、私はあなたがエラーが考える知っている可能性があり、ここで起こるが、私は知っている、それは決してことを合計確実に。」

すべての有効なコードがSwiftのコンパイル時型システムのボックスに収まるわけではありません—または 。つまり、任意の言語の静的型チェックに。エラーが発生しないことを論理的に証明できても、それをコンパイラに証明できない状況があります。そのため、Swiftの設計者が最初にこれらの機能を追加しました。

ただし、を使用するときはいつでも!、エラーの回復パスを除外することになります。つまり、…

2.感嘆符は潜在的なクラッシュです。

感嘆符には「Hey Swift、このエラーが発生することはないと確信しているので私の全体のアプリをクラッシュ、それはそれの回復パスは、コードに私のためであるより。」

それは危険な主張です。それは正しいものになる可能性があります。コードの不変条件について一生懸命考えたミッションクリティカルなコードでは、偽の出力がクラッシュよりも悪い可能性があります。

しかし、私が!実際に目にするときは、それほど注意深く使用されることはめったにありません。代わりに、あまりにも多くの場合、「この値はオプションであり、なぜ nilになる可能性があるのか​​、またはその状況を適切に処理する方法についてそれほど深く考えていませんでしたが、!とコンパイルされました…したがって、私のコードは正しいですか?」

感嘆符の傲慢さに注意してください。代わりに…

3.感嘆符は控えめに使用するのが最適です。

これらの!構成要素にはそれぞれ?、エラー/ nilのケースに対処するように強制する対応物があります。

  • 条件付きアンラップ: if let name = nameLabel?.text { ... }
  • オプション: var logo: UIImageView?
  • 条件付きキャスト: logo.image = thing as? UIImage
  • 失敗時の例外: try? NSJSONSerialization.JSONObjectWithData(data, [])

を使いたくなったら!?代わりになぜ使用しないのかを常に慎重に検討することをお勧めします。!操作が失敗した場合、プログラムのクラッシュは本当に最良の選択肢ですか?なぜその値はオプション/失敗可能ですか?

コードがnil / errorの場合に取ることができる合理的な回復パスはありますか?その場合は、コード化してください。

nilになる可能性がない場合、エラーが発生しない場合、コンパイラーがそれを認識できるようにロジックを作り直すための合理的な方法はありますか?もしそうなら、それを行います。コードはエラーが発生しにくくなります。

エラーを処理するための合理的な方法がない場合があり、単にエラーを無視して、誤ったデータを処理するほうが、クラッシュするよりも悪い場合があります。それらは強制アンラップを使用する時代です。

私は定期的にコードベース全体を検索し、コードベースの!使用をすべて監査しています。精査に耐える使用法はほとんどありません。(これを書いている時点で、Siestaフレームワーク全体には2つの インスタンスがありますがあります。)

それはあなたがあなたのコードで決して使用すべきでないと言っているのではありません! -それを注意深く使用すべきであり、決してそれをデフォルトのオプションにしないでください。


func isSubscriptionActive(receiptData: NSDictionary?) -> Bool { if(receiptData == nil) { return false; } return (hasValidTrial(receiptData!) || isNotExpired(receiptData!)) && isNotCancelled(receiptData!) } 与えられた3.それを書くより良い方法はありますか?
jenson-button-event 2016

あなたは言うことができますfunc isSubscriptionActive(receiptData: NSDictionary?) -> Bool { guard let nonNilReceiptData = receiptData else { return false} return (hasValidTrial(nonNilReceiptData) || isNotExpired(nonNilReceiptData)) && isNotCancelled(nonNilReceiptData) }
rkgibson2 2017年

感嘆符は安全チェックを回避しません。あなたが得る保証オプションがnilの場合、クラッシュを。オプションは常にチェックされています。これは、安全チェックを行うための非常に残忍な方法です。
gnasher729

@ gnasher729答えが述べているように、安全なランタイムエラーを優先して、コンパイル時の安全性チェックを回避します
ポールカントレル2018年

24

johnオプションですvar。したがって、nil値を含めることができます。値がnilでないことを確認するに!は、var名前の最後にa を使用します。

ドキュメントから

「オプションに値が含まれていることを確認したら、オプションの名前の末尾に感嘆符(!)を追加することで、その基になる値にアクセスできます。感嘆符は効果的に次のように述べています。使ってください。」

非nil値をチェックする別の方法は、

    if let j = json {
        // do something with j
    }

1
はい、私はドキュメントでそれを見ましたが、それでも不必要に思われます...私にとっては、john.apartment = number73「このオプションは間違いなく値があることを知っています。使ってください。」...
Troy

6
はい、ありますが、ポイントはデフォルトでSwiftがコンパイル時にエラーをキャッチしようとするということです。この変数にnilを含めることができないことがわかっている、またはわかっている場合は、感嘆符を使用してそのチェックを削除できます。
lassej 2014年

16

ここではいくつかの例を示します。

var name:String = "Hello World"
var word:String?

どこにwordオプションの値です。値が含まれる場合と含まれない場合があります。

word = name 

ここnameには値があるので、割り当てることができます

var cow:String = nil
var dog:String!

dog強制的にアンラップされる場所は、値が含まれている必要があることを意味します

dog = cow

nilアンラップに割り当てられているため、アプリケーションがクラッシュします


1
var c:Int = nil「Nilは指定された型 'int'を初期化できません」
Asususer

15

この場合...

varジョン:人!

つまり、Johnは最初は値がnilになり、設定されます。一度設定すると、再びnil-ledになることはありません。したがって、これは「暗黙的にアンラップされたオプション」であるため、便宜上、オプションの変数にアクセスするための簡単な構文を使用できます。


1
ありがとうございました。これを説明する次のリンクも見つけました。このタイプのタイプは、「暗黙的にアンラップされたオプション」と呼ばれます。stackoverflow.com/questions/24122601/...
Kaydell

5

Cファミリの言語を使用している場合は、「メモリアドレス0(NULL)である可能性のあるタイプXのオブジェクトへのポインタ」と考えるでしょう。動的にタイプされた言語を使用している場合は、 「おそらくタイプXであるが、未定義のタイプである可能性があるオブジェクト」を考えています。これらのどちらも実際には正しくありませんが、最初の方は遠回りですが。

あなたがそれを考えるべき方法は、それが次のようなオブジェクトであるかのようです。

struct Optional<T> {
   var isNil:Boolean
   var realObject:T
}

オプションの値をテストしfoo == nilて実際に返ってくるfoo.isNilとき、そしてfoo!それがfoo.realObjectアサーションで返ってくると言うときはfoo.isNil == falsefoo実際にnilの場合は、nil なので、これに注意することが重要です。foo!、それはランタイムエラーであるため、これ通常、値がnilにならないことが確実でない限り、代わりに条件付きletを使用することをお勧めします。この種の策略は、値がどこでもnilであるかどうかをテストせずに、言語を強く型付けできることを意味します。

実際には、作業はコンパイラーによって行われるため、実際にはそのようには動作しません。高レベルでは、Foo?とは別のタイプがあり、タイプをFoo受け入れるfuncがFoonil値を受け取るのを防ぎますが、低レベルでは、プロパティやメソッドがないため、オプションの値は真のオブジェクトではありません。実際には、強制アンラップ時に適切なテストでNULL(0)になる可能性のあるポインタである可能性があります。

次のように、感嘆符が型にある他の状況もあります。

func foo(bar: String!) {
    print(bar)
}

これは、強制アンラップでオプションを受け入れることとほぼ同じです。つまり、

func foo(bar: String?) {
    print(bar!)
}

これを使用して、技術的にオプションの値を受け入れるが、nilの場合はランタイムエラーが発生するメソッドを作成できます。Swiftの現在のバージョンでは、これは明らかにis-not-nilアサーションをバイパスするため、代わりに低レベルのエラーが発生します。一般的には良い考えではありませんが、別の言語からコードを変換するときに役立ちます。



3

C#に精通している場合、これは疑問符を使用して宣言されるNullable型のようなものです。

Person? thisPerson;

この場合の感嘆符は、次のようにnull許容型の.Valueプロパティにアクセスすることと同じです。

thisPerson.Value

2

値のない目的Cの変数は「nil」に等しいため(0やfalseと同じ「nil」の値を使用することも可能)、条件付きステートメントで変数を使用できました(値を持つ変数は「TRUE」と同じです) 'と値のないものは' FALSE 'に等しい)。

Swiftは「オプションの値」を提供することでタイプセーフを提供します。つまり、異なるタイプの変数を割り当てることによって形成されるエラーを防ぎます。

したがって、Swiftでは、ブール値のみを条件付きステートメントで提供できます。

var hw = "Hello World"

ここでは、「hw」は文字列ですが、目的Cのようなifステートメントでは使用できません。

//This is an error

if hw

 {..}

そのため、次のように作成する必要があります。

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}

2

!オブジェクトの最後に、オブジェクトはオプションであり、それ以外の場合はnilを返すことができる場合はアンラップすることを示します。これは、プログラムをクラッシュさせるエラーをトラップするためによく使用されます。


2

簡単に(!):変数を宣言し、変数が値を保持していることを確認した後。

let assumedString: String! = "Some message..."
let implicitString: String = assumedString

そうでなければ、値を渡した後に毎回これを行う必要があります...

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark

1

JohnはオプションのPersonです。つまり、値を保持することも、nilにすることもできます。

john.apartment = number73

johnがオプションでない場合に使用されます。ジョンはnilになることはないので、nil値でアパートメントを呼び出すことはありません。ながら

john!.apartment = number73

ジョンがnilではないことをコンパイラに約束し、オプションのラップを解除してジョンの値を取得し、ジョンのアパートメントプロパティにアクセスします。johnがnilでないことがわかっている場合は、これを使用してください。nilオプションでこれを呼び出すと、ランタイムエラーが発生します。

ドキュメントには、convertedNumberがオプションである、これを使用するための良い例が含まれています。

if convertedNumber {
    println("\(possibleNumber) has an integer value of \(convertedNumber!)")
} else {
    println("\(possibleNumber) could not be converted to an integer")
}

ジョンがnilで、私が行くjohn.apartment = number73場合、「!」を付けない限り、エラーにはなりません。ジョンの後?
Troy

johnがオプションの場合、コンパイラはnilではないことを知っている必要があるため、感嘆符を使用してそのプロパティにアクセスする必要があります。オプションではない場合、感嘆符は使用できません。
Connor

1
オプションのすべての変数に感嘆符を使用する必要がある場合、感嘆符がないことで同じことを意味するのではなく、なぜAppleが感嘆符を使用するのでしょうか。それは不必要な膨張のように見えます...または、オプションの変数で感嘆符を使用しないことが理にかなっているケースはありますか?
Troy

オプションをnil以外にする必要がある場合は、感嘆符を使用します。ジョンのプロパティにアクセスする場合のように。あなたはvar jackのような何かをすることができます:人?= johnここで、jackはオプションまたはvarジャックでもあります。Person = john!ジャックは人であり、nilではありません
Connor

右ですが、元の例では、johnオプションを逆参照しているという事実は、それを非nilにする必要があることをコンパイラに伝えてvar jack: Person = john!いませんか?そして、あなたの例では、?Person johnが非nilである必要があることをコンパイラに伝えた後?全体として、!ジャストは一種の冗長に思えます...それでも、「なぜ」の部分に何かが足りないように感じ!ます...
Troy

1

簡単に言えば、感嘆符はオプションがラップ解除されていることを意味します。オプションは、値を持つかどうかに関係なく変数です。そのため、ここ示すように if letステートメントを使用して変数が空かどうかを確認し、強制的にアンラップできます。空のオプションを強制的にアンラップすると、プログラムがクラッシュするので注意してください。オプションは、変数への明示的な割り当ての最後に疑問符を付けることによって宣言されます。

var optionalExample: String?

この変数には値がありません。アンラップすると、プログラムがクラッシュし、値がnilのオプションをアンラップしようとしたことがXcodeから通知されます。

お役に立てば幸いです。


1

簡単な言葉で

USING感嘆符は、変数が非nil値で構成される必要があることを示します(nilになることはありません)。


1

ストーリー全体は、オプション変数と呼ばれる迅速な機能から始まります。これらは、値がある場合とない場合がある変数です。一般的に、swiftでは初期化されていない変数を使用できません。これは、クラッシュや予期しない理由につながり、バックドアのプレースホルダーとして機能するためです。したがって、最初に値が決定されていない変数を宣言するには、「?」を使用します。そのような変数が宣言されている場合、それを何らかの式の一部として使用するには、使用前にアンラップする必要があります。アンラップは、変数の値がオブジェクトに適用されることを発見する操作です。アンラップせずに使用しようとすると、コンパイル時エラーが発生します。オプションの変数である変数をアンラップするには、感嘆符「!」使用されている。

このようなオプションの変数には、たとえばシステムまたは独自のプログラムによって値が割り当てられることがわかっていることがありますが、そのような状況で、疑問符「?」を使用してオプションの変数を宣言する代わりに、UIアウトレットなど を使用しております "!"。

したがって、システムは "!"で宣言されたこの変数を知っています。現在はオプションであり、値はありませんが、ライフタイムの後半で値を受け取ります。

したがって、感嘆符は2つの異なる使用法を保持します。1。オプションであり、後で確実に値を受け取る変数を宣言する2.式で使用する前にオプション変数をアンラップする。

上記の説明は、技術的なものの多くを避けています。


1

これをオプションとして使用すると、オプションがアンラップされ、何かが存在するかどうかが確認されます。if-elseステートメントで使用する場合は、NOTのコードです。例えば、

if (myNumber != 3){
 // if myNumber is NOT 3 do whatever is inside these brackets.
)

1

オプションの変数には値が含まれる場合と含まれない場合があります

ケース1: var myVar:String? = "Something"

ケース2: var myVar:String? = nil

ここでmyVar!を要求すると、1の場合に値を返すようにコンパイラーに指示します。 "Something"

ケース2ではクラッシュします。

意味!markは、存在しない場合でも、コンパイラに値を強制的に返します。それがForce Unwrappingという名前の理由です


@モリッツ。私はそれがそうであるか知りませんか?質問がすでに回答されている場合、私は回答できませんか?私は問題を引き起こしていますか、それとも私の答えに問題がありますか?理解できませんなぜ正解するために反対票を投じているのですか?コンセプトを理解した上で答えてみました。分かりやすく説明するのに役立つ人もいると思います。
Ashish Pisey 2017

@モリッツ今これは建設的です。これが理由であるなら、あなたは最初にこの修正を私に言ったはずです。フィードバックをお寄せいただきありがとうございます。修正しました。
Ashish Pisey 2017

0
Simple the Optional variable allows nil to be stored.

var str : String? = nil

str = "Data"

To convert Optional to the Specific DataType, We unwrap the variable using the keyword "!"

func get(message : String){
   return
}

get(message : str!)  // Unwapped to pass as String

1
以前の回答でカバーされていないものを追加していない回答を書かないでください。
Dalija Prasnikar

-1

自問してみてください

  • タイプperson?にはapartmentメンバー/プロパティがありますか?または
  • タイプpersonにはapartmentメンバー/プロパティがありますか?

この質問に答えられない場合は、読み続けてください。

理解するには、ジェネリックスの超基本的なレベルの理解が必要かもしれません。こちらをご覧ください。Swiftの多くはGenericsを使用して記述されています。オプションが含まれています

以下のコードは、このスタンフォードのビデオから入手できます。最初の5分間を視聴することを強くお勧めします

オプションは2つのケースのみを持つ列挙型です

enum Optional<T>{
    case None
    case Some(T)
}

let x: String? = nil //actually means:

let x = Optional<String>.None

let x :String? = "hello" //actually means:

let x = Optional<String>.Some("hello")

var y = x! // actually means:

switch x {
case .Some(let value): y = value
case .None: // Raise an exception
}

オプションのバインディング:

let x:String? = something
if let y = x {
    // do something with y
}
//Actually means:

switch x{
case .Some(let y): print)(y) // or whatever else you like using 
case .None: break
}

あなたが言うときあなたはvar john: Person?実際にそのような意味です:

enum Optional<Person>{
case .None
case .Some(Person)
}

上記の列挙型には、という名前のプロパティがありapartmentますか?どこかで見ますか?それはだないまったくあり!しかし、それを展開すると、つまり、person!次のことができます...フードの下で何が行われるか:Optional<Person>.Some(Person(name: "John Appleseed"))


var john: Person代わりに定義した場合:var john: Person?それ自体はのメンバーを持っている!ので、もはや使用する必要はありませんでした。Personapartment


!アンラップに使用することが推奨されないことがある理由に関する今後の議論として、このQ&Aを参照してください


2
上記の実際のスライドを使用すると、著作権が侵害される可能性があります「...スタンフォード大学は、iTunes Uコレクションのすべてのコンテンツの著作権を保持しています。」http://itunes.stanford.eduから。おそらくあなた自身の言葉で、この質問に答えるのに気づいたコースから学んだ内容に答えた方がいいでしょう(そして、スライドを使用する代わりに、コード形式でそれらの関連部分を引用して自然に引用してください)。
dfri 16

2
あなたの議論はargumentum ad populumです。とにかく、スタンフォードがここに来てDMCAの権利を行使することはないと思いますが、公式/有効な情報源に基づいて自分の言葉で回答し、上記のようにそれらの情報源を完全にコピーする形ではない方が常に良いでしょう。特に私たちが著作権で保護されたスライドについて話すとき:繰り返しになりますが、スライドのコンテンツをコードブロックで引用する方が適切です(コードの画像は通常、ここでは禁止事項です!)。
dfri 16

1
私がリンクしたメタ投稿は、SO:のアプローチを説明しています。このような投稿は、ランダムなユーザーが著作権侵害として報告した場合、当然削除されません。たとえば、スタンフォードの担当者の場合のみです。ここに来て、削除されるポストとして、それ強制する必要があります。したがって、「スタンフォード大学がここに来てDMCAの権利を行使するとは思わないと書きました。上記の私のポイントは、これは著作権侵害の可能性があると私は信じていますが(これは間違っていると思います)、当然のことながら、誰もこれを強制することはありません。...
dfri 16

1
しかし、これはさておき、コードの画像を含む質問や回答を投稿することは、いくつかの理由で直立させられません。まとめると、私はこれらのコメントで指摘しましたが、2つの主な理由(著作権で保護されたスライド、コードのイメージ)のため、この回答は現在の形式では完全に良いとは言えないと思います。当然、私も含めて誰もこれについて何もしません。私は単に将来の参照のために私たちにそれを指摘しています(または、代わりにコードブロックによる引用でこの投稿を編集することをお勧めします)。同意、iTunes U!:)
dfri 16

2
@dfriで削除された画像
Honey
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.