サーチ…


前書き

"任意の値には値が含まれているか、または値が存在しないことを示すnilが含まれています"

抜粋:Apple Inc.「Swiftプログラミング言語(Swift 3.1版)」から抜粋。iBooks。 https://itun.es/us/k5SW7.l

基本的なオプションの使用例には、定数(let)、ループ内のオプション(if-let)の使用、メソッド内の任意の値の安全なアンラッピング(guard-let)、スイッチループの一部としてのcase )、合致演算子(??)を使用してnilの場合はデフォルト値になります。

構文

  • var optionalName:optionalType? //オプションの型を宣言し、デフォルトはnil
  • var optionalName:optionalType? = value //オプションで値を宣言する
  • varオプション名:optionalType! //暗黙的にアンラップされたオプションを宣言する
  • オプション! //オプションのアンラップを強制する

備考

オプションの詳細については、Swiftプログラミング言語を参照してください。

オプションの種類

オプションは、ラッパーとして機能する一般的な列挙型です。このラッパーは、変数が2つの状態のうちの1つを持つことを可能にします。ユーザー定義型の値または値が存在しないことを表すnilです。

この能力はSwiftでは特に重要です。なぜなら、言語の設計目標の1つがAppleのフレームワークでうまく動作するからです。 Appleのフレームワークの多く(ほとんど)は、Objective-CのプログラミングパターンとAPI設計の使いやすさと重要性から、 nil利用しています。

Swiftでは、変数がnil値を持つためには、オプションでなければなりません。オプションを作成するには、 !または?変数型に変換します。たとえば、 Intオプションにするには、

var numberOne: Int! = nil
var numberTwo: Int? = nil

?オプションは明示的にラップ解除されていなければならず、変数にアクセスするときに変数に値があるかどうかが不明な場合に使用する必要があります。たとえば、文字列をIntに変換すると、結果はオプションのInt?文字列が有効な数値でない場合にはnilが返されるためです

let str1 = "42"
let num1: Int? = Int(str1) // 42

let str2 = "Hello, World!"
let num2: Int? = Int(str2) // nil

!オプションは自動的にアンラップされ、アクセスするときに変数に値があることが確実である場合にのみ使用してください。たとえば、グローバルUIButton! viewDidLoad()初期化される変数

//myButton will not be accessed until viewDidLoad is called,
//so a ! optional can be used here
var myButton: UIButton!

override func viewDidLoad(){
    self.myButton = UIButton(frame: self.view.frame)
    self.myButton.backgroundColor = UIColor.redColor()
    self.view.addSubview(self.myButton)
}

オプションのアンラッピング

Optionalの値にアクセスするには、アンラップする必要があります。

あなたは条件付きで使用してオプションをアンラップオプションの結合力を使ってオプションをアンラップすることができます!オペレーター。

条件付きでアンラッピングすると、「この変数に値がありますか? force unwrappingは "This variable is a value!"というメッセージを表示します。

変数nilを強制的に解除すると、オプションの例外とクラッシュをアンラッピングしながら予期せず見つかったnilがスローされますので、使用する場合は注意深く検討する必要があります!適切である。

var text: String? = nil
var unwrapped: String = text! //crashes with "unexpectedly found nil while unwrapping an Optional value"

安全なアンラップのために、 if-letステートメントを使用することができます。ifステートメントは、ラップされた値がnil場合、例外をスローしたりクラッシュしたりしません。

var number: Int?
if let unwrappedNumber = number {       // Has `number` been assigned a value?
    print("number: \(unwrappedNumber)") // Will not enter this line
} else {
    print("number was not assigned a value")
}

または、 ガードステートメント

var number: Int?
guard let unwrappedNumber = number else {
    return
}
print("number: \(unwrappedNumber)")

unwrappedNumber変数のスコープは、 if-letステートメントの内側で、 guardブロックの外側にあることに注意してください。

多くのオプションのアンラップをチェーンすることができます。これは主に、コードが正しく実行されるために変数を必要とする場合に便利です。

var firstName:String?
var lastName:String?

if let fn = firstName, let ln = lastName {
    print("\(fn) + \(ln)")//pay attention that the condition will be true only if both optionals are not nil.
}

テストを成功させるためには、すべての変数をアンラップしなければならないことに注意してください。さもなければ、アンラップされた変数とアンラップされなかった変数を判別する方法がありません。

選択肢をアンラップした直後に条件文をチェーンすることができます。これは、ネストされたif-elseステートメントを意味しません!

var firstName:String? = "Bob"
var myBool:Bool? = false

if let fn = firstName, fn == "Bob", let bool = myBool, !bool {
    print("firstName is bob and myBool was false!")
}

無用合体オペレータ

値がnilでなければ、 nil coalescing演算子を使用して値をアンラップすることができます。そうでない場合は、別の値を指定します。

func fallbackIfNil(str: String?) -> String {
    return str ?? "Fallback String"
}
print(fallbackIfNil("Hi")) // Prints "Hi"
print(fallbackIfNil(nil)) // Prints "Fallback String"

この演算子は短絡することができます。つまり、左のオペランドがnil以外の場合、右のオペランドは評価されません。

func someExpensiveComputation() -> String { ... }

var foo : String? = "a string"
let str = foo ?? someExpensiveComputation()

この例では、 fooは非nil someExpensiveComputation()someExpensiveComputation()は呼び出されません。

また、複数のnil合体ステートメントを連鎖させることもできます。

var foo : String?
var bar : String?

let baz = foo ?? bar ?? "fallback string"

この例では、 bazは、nullでない場合はfooのラップされていない値が割り当てられ、そうでない場合は、nilでない場合はbarのラップされていない値が割り当てられます。そうでない場合、フォールバック値が割り当てられます。

オプションの連鎖

オプションの連鎖を使用すると、 メソッドを呼び出したり、 プロパティまたは添字にオプションでアクセスしたりすることができます。これは?与えられたオプションの変数と指定されたメンバ(メソッド、プロパティ、または添字)の間にあります。

struct Foo {
    func doSomething() {
        print("Hello World!")
    }
}

var foo : Foo? = Foo()

foo?.doSomething() // prints "Hello World!" as foo is non-nil

fooに値が含まれている場合は、 doSomething()が呼び出されます。場合fooあるnil場合、悪い何も起こりません-コードは、単に静かに失敗し、実行を継続します。

var foo : Foo? = nil

foo?.doSomething() // will not be called as foo is nil

(Objective-Cではメッセージをnilに送信するのと同じ動作です)

Optional Chainingがそのように命名される理由は、あなたが呼出し/アクセスするメンバーを通して「オプション性」が伝播するからです。つまり、オプションの連鎖で使用されるメンバーの戻り値は、オプションとして入力されたかどうかにかかわらず、オプションになります。

struct Foo {
    var bar : Int
    func doSomething() { ... }
}

let foo : Foo? = Foo(bar: 5)
print(foo?.bar) // Optional(5)

ここでfoo?.barInt?返しInt? barはオプションではありませんが、 foo自体はオプションです。

オプション性が伝播すると、 Voidを返すメソッドはVoidを返しVoid?オプションの連鎖で呼び出されたときこれは、メソッドが呼び出されたかどうかを判断するために役立ちます(したがって、オプションに値がある場合)。

let foo : Foo? = Foo()

if foo?.doSomething() != nil {
    print("foo is non-nil, and doSomething() was called")
} else {
    print("foo is nil, therefore doSomething() wasn't called")
}

ここではVoid?比較していVoid?メソッドが呼び出されたかどうかを判断するためにnilを返す(したがってfooがnilでないかどうか)。

概要 - なぜオプション?

プログラミングの際に、値を持つ変数とそうでない変数を区別する必要があることがよくあります。 Cポインタのような参照型では、 nullような特殊な値を使用して変数に値がないことを示すことができます。整数などの組み込み型の場合は、より困難です。指定された値(-1など)を使用できますが、これは値の解釈に依存します。それはまた、通常の使用からの "特別な"価値を排除します。

これに対処するために、Swiftは任意の変数をオプションとして宣言することができます。これは?または!型の後( オプションの型を参照)

例えば、

var possiblyInt: Int?

整数値を含む場合と含まない場合がある変数を宣言します。

特別な値nilは、現在この変数に値が割り当てられていないことを示します。

possiblyInt = 5      // PossiblyInt is now 5
possiblyInt = nil    // PossiblyInt is now unassigned

nilを使って、割り当てられた値をテストすることもできます:

if possiblyInt != nil {
    print("possiblyInt has the value \(possiblyInt!)")
}

!の使用に注意してください!オプションの値をラップ解除するprint文に

オプションの一般的な使用例として、数字を含む文字列から整数を返す関数を考えてみましょう。文字列に数字以外の文字が含まれていたり、空であったりする可能性があります。

単純なIntを返す関数は、どのように失敗を示しますか?特定の値を返すことで、その値が文字列から解析されないようにすることはできません。

var someInt
someInt = parseInt("not an integer") // How would this function indicate failure?

しかし、Swiftでは、その関数は単純にオプションの Intを返すことができます 。その後、失敗はnil戻り値で示されます。

var someInt?
someInt = parseInt("not an integer")  // This function returns nil if parsing fails
if someInt == nil {
    print("That isn't a valid integer")
}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow