【初心者必見】iphoneアプリ開発_型の基礎・基本
最終更新日:2020年08月14日
家に引きこもっている「ゴルトン社長」です。(twitter : @GoRuton_1stStep)
今日は、swift特有のOptional型の解説を記載しました
- 人気の記事!
- 1)Optional 型の基本
- 2)ラップ(wrap)とアンラップ(unwrap)
- Optional 型をアンラップする方法
- 3) Implicitly Unwrapped Optional 型とは?
- 4) Optional 型の代入演算子
- 参考リンク
- iphone参考記事
- 最後に!!
人気の記事!
人生を変えたい人に向けて「はじめの一歩」を踏み出したい人にオススメ!
www.goruton.com www.goruton.com www.goruton.com www.goruton.com
1)Optional 型の基本
Optional 型とは?
- Optional 型 - nil の代入を許す
- 非 optional 型 - nil の代入を許さない
var a: Int? // Optional 型 var b: Int // 非 optional 型 var c: String? // Optional 型 var d: String // 非 optional 型 var e: Int? var f: Optional<Int> // Int? と同じ意味. T? は Optional<T> のシンタックスシュガーである
シンタックスシュガーとは?
- プログラミング言語において、既存の構文などを別の構文や記法で記述できるようにしたもの。 - 長い構文を簡略に記述できるようにしたり、複雑な構文を見やすくするために用意されることが多い。 - 糖衣構文などと訳される。
nilとは?
- nilとはデータが無い、変数が空の状態を表します。
- iOSではnilに対して操作することでアプリケーションが落ちてしまうことがありました。
- そのような問題を解決するためにswiftではnilを基本的には許容しません。
- しかし、オプショナル型を使うことでnilを扱うことができるようになります。
Optional は enum 型である
- Optional
は、標準ライブラリの中で enum 型として定義されている。
enum Optional<T> : Reflectable, NilLiteralConvertible { case None // nil に相当する case Some(T) // T 型(素の型)の値が入る(Int 型や String 型の値など) ... }
Optional 型は nil が代入されるのを許す
- 非 optional 型に nil を代入しようとすると、コンパイラエラーが発生する。
- 非 Optional 型の場合、初期値には何も入っていない(nilも入っていない)
var a: Int? // Optional 型 a = nil // -> OK var b: Int // 非 optional 型 b = nil // -> Compiler error: Type 'Int' does not conform to protocol 'NilLiteralConvertible' var a: Int? // Optional 型 println(a) // -> nil var b: Int // 非 optional 型 println(b) // -> Compiler erorr: Variable 'b' used before being initialized
Optional 型は、非 Optional 型と同じようには扱えない
- 下記のように,Int? 型は、Int 型とは別の型なので、同じように操作することはできない。
- Int 型と同じように操作するためには、変数を「アンラップ」する必要がある(後述)。
var a: Int = 1 println(a + 2) // -> 3 var b: Int? = 1 println(b + 2) // -> Compiler error: Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?
2)ラップ(wrap)とアンラップ(unwrap)
「ラップされている」とは?「アンラップする」とは?
- Optional 型(Optional
型)の変数のことを「ラップされている」と言う - Optional
型に T 型の変数が「包まれている」ことに由来すると思われる - Optional 型(Optional
型)から T 型の変数を取り出すことを、「アンラップする」と言う。
Optional 型をアンラップする方法
Optional 型の変数をアンラップする方法として、以下のものがある。
- Forced unwrapping
- Optional chaining
- Optional binding
- 比較演算子
Forced unwrapping
- 「!」 を optional 型の変数の後ろに付けるとアンラップすることができる。
- これを Forced unwrapping と言う。
class Dog { func bark() -> String { return "Wan!" } } var wrappedDog: Dog? = Dog() // Optional 型 // // アンラップをしないと、bark() メソッドを呼び出すことができない // println(wrappedDog.bark()) // -> Compiler error: 'Dog?' does not have a member named 'bark' //「!」 を optional 型の変数の後ろに付けるとアンラップすることができる。 // これを Forced unwrapping と言う。 // // Forced unwrapping // println(wrappedDog!.bark()) // -> Wan! // // Forced unwrapping でnil をアンラップしようとすると、ランタイムエラーが発生する。 wrappedDog = nil println(wrappedDog!.bark()) // -> Runtime error: unexpectedly found nil while unwrapping an Optional value
Optional chaining
- 「?」 を使ってアンラップすることを optional Chaining と言う。
// // Optional Chaining // println(wrappedDog?.bark()) // -> Optional("Wan!") // Optional chaining で nil をアンラップしようとすると、nil が返ってくる。 wrappedDog = nil println(wrappedDog?.bark()) // -> nil
- Forced unwrapping はアンラップをした後に、最終的な戻り値をそのまま返す。
- 以下の場合、bark メソッドの戻り値(String 型)をそのまま返す。
// // Forced unwrapping // println(wrappedDog!.bark()) // -> Wan!
注意: Optional Chaining は Optional 型を返す
<理由>
1 optional chaining が nil を返す可能性があるためである。
2 アンラップ対象の変数が nil だった場合、optional chaining はランタイムエラーを起こさずに nil を返す。
3 nil を許容するためには、戻り値は optional 型でなければならない。
- Optional chaining はアンラップをした後に、最終的な戻り値を optional 型にラップしてから返す。
- 以下の場合、bark メソッドの戻り値(String 型)を optional 型にラップしてから返す。
// // Optional chaining // println(wrappedDog?.bark()) // -> Optional("Wan!")
上記の命令では以下の処理が行われている。
1 wrappedDog をアンラップする
2 bark() メソッドを呼ぶ
3 bark() メソッドが String 型を返す
4 String 型を optional 型にラップする
5 Optional
注意:「?」には二つの別の意味がある
どちらも「?」を使っているが、意味が異なるので混同しないように注意。
var a: Int? // Optional 型宣言の意味 println(wrappedDog?.bark()) // -> Optional("Wan!") // Optional chainingの意味
Optional binding
- if や while 文の条件式で宣言され、optional 型の変数を代入された変数は、非 optional 型になる。
- これを「optional binding」と言う
var wrappedDog: Dog? = Dog() // Optional 型 // Optional binding if var unwrappedDog = wrappedDog { // unwrappedDog はアンラップされた値(素の Dog 型)になる // varではなくてもletでも使用可能 // unwrappedDog は非 optional 型なので、アンラップは不要 println(unwrappedDog.bark()) // -> Wan! } // while文でもOK while var unwrappedDog = wrappedDog { println(unwrappedDog.bark()) // -> Wan! break } // wrappedDog が nil だった場合、条件式は false になる wrappedDog = nil if var unwrappedDog = wrappedDog { // false println("This is not printed out.") }
比較演算子
比較演算子を使うと、optional 型の変数が自動的にアンラップされる
var wrappedInt: Int? = 1 // Optional 型 // 自動的にアンラップされる println(wrappedInt == 1) // -> true println(wrappedInt >= 1) // -> true println(wrappedInt > 1) // -> false println(wrappedInt <= 1) // -> true println(wrappedInt < 1) // -> false println(wrappedInt != 1) // -> false //Optional 型の変数を比較演算子の右に置いてもかまわない。 println(1 == wrappedInt) // -> true //Optional 型の変数が nil であっても、エラーは発生しない。 wrappedInt = nil println(wrappedInt == 1) // -> false //注意: nil は負の無限大より小さい println(nil < -Double.infinity) // -> true var wrappedDouble: Double? = nil if wrappedDouble < 0.0 { println("\(wrappedDouble) is a negative number.") // -> nil is a negative number. }
3) Implicitly Unwrapped Optional 型とは?
「自動的にアンラップされる optional 型」のことである。
Implicitly Unwrapped Optional 型の宣言方法
「?」ではなく、「!」を使う
var a: Int! // Implicitly unwrapped optional 型 var b: Int? // Optional 型 var c: String! // Implicitly unwrapped optional 型 var d: String? // Optional 型 // T! は、ImplicitlyUnwrappedOptional<T> のシンタックスシュガーである var e:ImplicitlyUnwrappedOptional<Int> // つまり,Int! と同じ
ImplicitlyUnwrappedOptional は enum 型である
- ImplicitlyUnwrappedOptional
は標準ライブラリの中で enum 型として定義されている。
enum ImplicitlyUnwrappedOptional<T> : Reflectable, NilLiteralConvertible { case None // nil に相当する case Some(T) // T 型(素の型)の値が入る(Int 型や String 型の値など) ... }
Implicitly Unwrapped Optional 型の初期値は nil
var a: Int! // Implicitly unwrapped optional 型 println(a) // -> nil
Implicitly Unwrapped Optional 型は自動的にアンラップされる
var iwrappedDog: Dog! = Dog() // Implicitly unwrapped optional 型 // 「!」や「?」を付けなくても、自動的にアンラップされる println(iwrappedDog.bark()) // -> Wan!
nil をアンラップしようとすると、ランタイムエラーが発生する。
iwrappedDog = nil println(iwrappedDog.bark()) // -> Runtime error: unexpectedly found nil while unwrapping an Optional value
「!」には二つの別の意味がある
1) Implicitly unwrapped optional 型の宣言
2) Forced unwrapping
var a: Int! // Implicitly unwrapped optional 型 (1) var wrappedDog: Dog? = Dog() // Optional 型 // Forced unwrapping println(wrappedDog!.bark()) // -> Wan! (2)
4) Optional 型の代入演算子
var wrapped: Int? = 1 // Optional 型 var iwrapped: Int! = 2 // Implicitly unwrapped optional 型 var unwrapped: Int = 3 // 非 optional 型 //Optional 型は、implicitly unwrapped optional 型に代入できる。 //Implicitly unwrapped optional 型は、optional 型に代入できる。 iwrapped = wrapped // OK wrapped = iwrapped // OK //Forced unwrapping でアンラップされた optional 型は、非 optional 型に代入できる。 unwrapped = wrapped! // OK //Optional 型は、非 optional 型に「代入できない」。 unwrapped = wrapped // Compiler error: Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'? //Implicitly unwrapped optional 型は、 非 optional 型に代入できる //(暗黙的にアンラップされていることに注意)。 unwrapped = iwrapped // OK //Optional chaining でアンラップされた optional 型は、非 optional 型に「代入できない」 //(optional chaining の戻り値が optional 型であるため)。 unwrapped = wrapped? // Compiler error: Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'? //非 optional 型は、optional 型やimplicitly unwrapped optional 型に代入できる。 wrapped = unwrapped // OK iwrapped = unwrapped // OK
?? 演算子
1) a が nil でなければ、a!(a をアンラップしたもの) を返す。
2) a が nil であれば、b を返す。
つまり,a ?? b は、a != nil ? a! : bのシンタックスシュガーである
(1) var a: Int? = 1 // a は nil でないので、a をアンラップしたものを返す println(a ?? 2) // -> 1 println(a != nil ? a! : 2) // -> 1 (2) a = nil // a は nil なので、2 を返す println(a ?? 2) // -> 2
参考リンク
- [Swift] Optional 型についてのまとめ Ver2 - Qiita
- nilとオプショナルについて | Swift入門編 - ウェブプログラミングポータル
- どこよりも分かりやすいSwiftの"?"と"!" - Qiita
iphone参考記事
https://bluethree-gift.hatenablog.com/archive/category/iphone%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA__%E5%88%9D%E5%BF%83%E8%80%85bluethree-gift.hatenablog.com
最後に!!
最後までご覧いただき、本当にありがとうございます!!
最近は、たくさんの読者さんから「コメント」や「メッセージ」が届くようになりました!!
皆さんと会話できて嬉しいですし、コメントで毎日励まされています。
ありがとうございます!
これからも、ゴルトン社長は「毎日」ブログを更新しています! www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com
皆さんから人気がある記事
www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com
まとめ記事
www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com www.goruton.com