0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Optional型の目的とラップ/アンラップ

Last updated at Posted at 2024-12-13

Optional型とは

Optionalは、値が存在するかどうかを表す型。Swiftでは、安全性を担保するために、原則nilを許容しない。例外として、nilを許容する場合、Optional型を使う。

目的

安全性の向上。
「値が存在しない状態(nil)を明示的に扱える。そうすると、nilに関連するエラーがコンパイル時に検知できる。
コンパイル時にエラー検知することで、実行時エラー(例えば、値があると思ったが、実際はnilだった)を回避できる。

使い方

ラップ

値がない場合: nil

let noValue: Int? = nil

値がある場合: .someまたは簡略表記

let someValue: Int? = .some(42)
let shorthandValue: Int? = 42

アンラップ

1. 強制

let value: Int? = 42
print(value!) // 42

補足
強制アンラップの多用には注意が必要。Swiftはプログラムのバグをコンパイル時に検出することで安全性を高める設計思想をもつ言語。そのため、強制アンラップの多用はその思想に反してエラー検知を実行時まで先延ばしにすることを意味する。

2. オプショナルバインディング

①if let

let optionalValue: Int? = 42

print(type(of: optionalValue)) // Optional<Int>

if let unwrapped = optionalValue {
    print(type(of: unwrapped)) // Int
    print("アンラップされた値: \(unwrapped)")
} else {
    print("値は存在しません")
}

②guard let

func printValue(_ value: Int?) {
    guard let unwrappedValue = value else {
        print("値は存在しません")
        return
    }
    print("値は存在します: \(unwrappedValue)")
}

let optionalValue: Int? = 42
printValue(optionalValue) // 値は存在します: 42

let nilValue: Int? = nil
printValue(nilValue) // 値は存在しません

3. デフォルト値を設定

let result = someValue ?? 0

4. オプショナルチェーン

下記のサンプルで、user.addressに値が存在する場合、cityにアクセス。一方、user.addressnilの場合、チェーンを中断し、?.cityは実行されず、nilを返す。nilを返してもクラッシュしない理由は、オプショナルチェーンの仕様。

struct User {
    var name: String
    var address: Address?
}

struct Address {
    var city: String
    var postalCode: String
}

var user = User(name: "John", address: nil)
var cityName = user.address?.city //?.cityは実行されず、チェーンを中断。
print(cityName) // nil(クラッシュしない)

user.address = Address(city: "New York", postalCode: "10001")
cityName = user.address?.city 
print(cityName)// Optional("New York")

補足

nilOptional()は、
下記Swiftの標準ライブラリに下記のEnum型が定義されているから使える。

enum Optional<Wrapped> {
    case none // nil
    case some // 値が存在する
}
let none = Optional<Int>.none 
print("none: \(String(describing: none))") //none: nil

let some = Optional<Int>.some(1)
print("some: \(String(describing: some))") //some: Optional(1)

参考:石川 洋資; 西山 勇世. [増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 WEB+DB PRESS plus (p.123). 株式会社技術評論社. Kindle 版. https://amzn.asia/d/i8oLYYp

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?