2016-11-30 4 views
2

は、2つの変数、オプションのxと暗黙的に開封されたオプションyです:この2つのoptionalsの暗黙のうちにアンラップされたオプションをアンラップするのはなぜですか?私は、文字列の補間はここスウィフト3でどのように機能するかを理解することはできません

let x: Int? = 1 
let y: Int! = 2 

印刷はかなりロジックになります:

print(x) // Optional(1) 
print(y) // 2 

しかし、なぜ文字列補間が他の方法で機能しますか?

print("x: \(x)") // x: Optional(1) 
print("y: \(y)") // y: Optional(2) 

まだアンラップされたオプションをアンラップするのはなぜですか?

print("y: \(y!)") // y: 2 

のは、ここで仮定しましょうがStringInt!を変換するdescriptionプロパティを使用していますCustomStringConvertibleプロトコルを使用しました。しかし、なぜここにはないy: Optional(2)ですか?

print("y: \(y!.description)") // y: 2 
print("y: \(y?.description)") // y: Optional("2") 
print("y: \(y.description)") // y: 2 

誰でも説明できますか?

答えて

1

printは、独自の内部動作の一部として、オプション(通常の、自分で処理していない種類)をアンラップします。文字列の補間はあなたのためにこれを行いません、あなたはそれを与えるだけで変換します。ここで

は、最後の例の説明です:

  • print("y: \(y!.description)") // y: 2

    yは、そのIntコンテンツを提供するために、明示的に開封されているタイプInt!を持っています。 descriptionが呼び出されます。 descriptionStringを返します。 yがnilの場合、これはクラッシュします。

  • print("y: \(y?.description)") // y: Optional("2")

    オプションの連鎖は、それが非nilのだ場合、yのみdescriptionを呼び出すために使用されています。 nilの場合は、最初に説明が呼び出されず、nilが伝播されます。この式の結果はString?です。 Int!として

  • print("y: \(y.description)") // y: 2

    y、ケース1と同様に開始するが、この時間Intコンテンツを与えるために、開封された暗黙あります。 descriptionが呼び出されます。 descriptionStringを返します。 yがnilの場合、これはクラッシュします。

+1

回答ありがとうございました。第2のケースでは「文字列?」に関する素晴らしい点があります。しかし、 'print(" y:\(y) ")'が 'y:Optional(2)'を与える理由は説明していません。編集:重複タグ – Leo

+1

これは、これがリンクされている他の質問に記載されているように、型システムの欠点です。うまくいけばそれは修正されますが、私はそれ以上の睡眠を失うことはありません。暗黙のうちにラップされていないオプションを使用しないでください。IBOutletsと再帰的なクロージャーを除いて、ほとんどの場合、それらの理由はありません。 – Alexander

+0

Obj-CとSwiftの相互作用が主な原因です。私にとっては、「初期化時に定義できない定数」でした。しかし、SE-0054は本当に "暗黙的にアンラップされたオプション"を "シュレーディンガーのオプション"に変換します。 – Leo

関連する問題