web-dev-qa-db-ja.com

Swift optionalsをどのように展開しますか?

通常のオプションと暗黙のオプションの両方を適切にアンラップするにはどうすればよいですか?

このトピックには混乱があるようで、すべての方法とそれらがどのように役立つかについての参照を希望します。

現在、オプションを作成するには2つの方法があります。

var optionalString: String?

var implicitOptionalString: String!

両方を解く方法は何ですか?また、アンラップ中に!?を使用することの違いは何ですか?

16
ktzhang

多くの類似点があり、わずかな違いがあります。

(通常)オプション

  • 宣言:_var opt: Type?_

  • 安全でないラップ解除:_let x = opt!.property // error if opt is nil_

  • 安全に存在をテストする:if opt != nil { ... someFunc(opt!) ... } // no error

  • バインディングによる安全なアンラップ:if let x = opt { ... someFunc(x) ... } // no error

  • 安全な連鎖:_var x = opt?.property // x is also Optional, by extension_

  • Nil値を安全に合体:_var x = opt ?? nonOpt_

暗黙的にアンラップされたオプション

  • 宣言:_var opt: Type!_

  • 安全でないアンラップ(暗黙):_let x = opt.property // error if opt is nil_

    • 割り当てによる安全でないアンラップ:
      _let nonOpt: Type = opt // error if opt is nil_

    • パラメータ渡しによる安全でないアンラップ:
      func someFunc(nonOpt: Type) ... someFunc(opt) // error if opt is nil

  • 安全に存在をテストする:if opt != nil { ... someFunc(opt) ... } // no error

  • 安全な連鎖:_var x = opt?.property // x is also Optional, by extension_

  • Nil値を安全に合体:_var x = opt ?? nonOpt_

49
jtbandes

Beta 5以降、新しい合体演算子(??)も追加されました。

var a : Int?
let b : Int = a ?? 0

オプションが!= nilの場合はラップ解除され、それ以外の場合は演算子の右側の値が使用されます

7
valfer

オプションのタイプは、変数がnilになる可能性があることを意味します。

例:

var myString: Int? = 55
myString = nil

疑問符は、値がnilの可能性があることを示しています。

しかし、あなたがこのように述べれば:

var myString : Int = 55
myString = nil

エラーが表示されます。

次に、値を取得するために、ラップを解除する必要があります。

print(myString!)

しかし、自動的にアンラップしたい場合:

var myString: Int! = 55

次に:

print(myString)

アンラップする必要はありません。お役に立てば幸いです。

2
Raj Aryan

オプションの値をアンラップするアプローチを作成しました:

// MARK: - Modules
import Foundation
import UIKit
import CoreData

// MARK: - PROTOCOL
protocol OptionalType { init() }

// MARK: - EXTENSIONS
extension String: OptionalType {}
extension Int: OptionalType {}
extension Double: OptionalType {}
extension Bool: OptionalType {}
extension Float: OptionalType {}
extension CGFloat: OptionalType {}
extension CGRect: OptionalType {}
extension UIImage: OptionalType {}
extension IndexPath: OptionalType {}
extension Date: OptionalType {}
extension UIFont: OptionalType {}
extension UIColor: OptionalType {}
extension UIViewController: OptionalType {}
extension UIView: OptionalType {}
extension NSMutableDictionary: OptionalType {}
extension NSMutableArray: OptionalType {}
extension NSMutableSet: OptionalType {}
extension NSEntityDescription: OptionalType {}
extension Int64: OptionalType {}
extension CGPoint: OptionalType {}
extension Data: OptionalType {}
extension NSManagedObjectContext: OptionalType {}

prefix operator ?*

//unwrapping values
prefix func ?*<T: OptionalType>( value: T?) -> T {
    guard let validValue = value else { return T() }
    return validValue
}

カスタムデータ型を追加することもできます。

使用法:-

var myString = ?*str

それが役に立てば幸い :)

2
Pratyush Pratik

特定のタイプの拡張を作成し、デフォルト値で安全にアンラップすることもできます。私は同じことのために次のことをしました:

extension Optional where Wrapped == String {
    func unwrapSafely() -> String {
        if let value = self {
            return value
        }
        return ""
    }
}
0
Anil Arigela