引き続きお気に入りな技術ブログ「その Swift コード、こう書き換えてみないか」を眺めていきます。その中の「オプショナルなプロパティーが nil
でないときに〜」から、今回は見ていくことになりそうです。有名な機能のようなそうでもないような、書いて見やすいコードになるようなそうでもないような、個人的には有用ながらも微妙な心地を感じる機能な印象なので、この気にみんなと改めて印象を整理していけたらいいなと思っています。よろしくお願いしますね。
そんな今回は 福岡県福岡市 からの配信になります。
—————————————————————————————————————————————— 熊谷さんのやさしい Swift 勉強会 #269
00:00 開始 00:35 Optional.map 01:56 Optional.map の定義 03:31 Optional.map って使う? 04:06 スマートに1行でまとめられる 07:51 Swift 5.9 からの if 式 11:18 条件演算子は今回の場面では冗長な印象 12:52 switch 式で記述してみる 14:03 確定初期化はよく使う? 18:00 if 式はプロパティーの初期化でも使える 22:30 if 式のブロック内は単一ステートメント 23:32 Optional.map を使うのも良いアイデア 24:40 確定初期化を使う場面 25:54 オプショナル型な変数の初期値は nil 27:09 昔の人ほど確定初期化を使わないかもしれない 29:26 不必要な可変性は持たせない 31:04 オブジェクトの初期化と確定初期化の類似性 32:00 初期化漏れがないかコンパイラーによって検査される 33:00 お好み焼き名前空間における対象地域 34:41 lazy var と preconditionFailure を合わせた問題提起 37:52 どこまでの範囲を表現するかは状況次第 38:49 クロージング ——————————————————————————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #269
では始めていきますね。今日も引き続きSwift言語の勉強会を進めていきます。なかなか楽しいプログラムです。以前の提案で、トリックやコードを書き換えてみるプログラムがありましたが、それがとてもよかったですね。引き続き見ていきましょう。
さて、今回の話題はオプショナルなプロパティについてです。オプショナルのプロパティがNil
ではないときに特定の処理を行い、Nil
の場合はそのままにするにはmap
を使う方法があります。これはあまり知られていないこともありますが、なかなか良いテクニックです。
では早速見ていきましょう。この例を作るための下準備をしていきます。まず、オプショナルのString型の変数selectiveTalkTitle
を用意します。これに何か値が入っている場合、それをTalk
型に変換します。selectiveTalkTitle.map
と書いて、クロージャを指定してあげると、Nil
ではないときにはそのクロージャに値が渡り、処理されて結果が返ってきます。Nil
の場合はNil
がそのまま返るというメソッドです。
ここで重要なのは、一般的にmap
は配列やシーケンスに対して使われることが多いですが、オプショナル型に対しても使えるという点です。オプショナルがNil
かどうかで処理が分岐し、Nil
でなければクロージャが呼び出され、処理された結果が返ります。Nil
の場合はそのままNil
が返るわけです。この時、クロージャの型は元の型Tを受け取って、型Uを返し、map
全体が返すのはU?
となります。これにより、処理が行われても行われなくても、オプショナル型で返すというのがポイントです。
次に、コードを見てみましょう。下記のように書いています。
let selectiveTalkTitle: String? = "Some title"
let transformedTalk = selectiveTalkTitle.map { title in
return Talk(title: title)
}
このようにして、selectiveTalkTitle
がNil
でなければTalk
型に変換できます。一方、Nil
であればそのままNil
を返します。
オプショナル型の取り扱い方法といえば、普段のコーディングでももう少し工夫が必要な時があります。例えば、オプショナルバインディングを使うif let
やguard let
もありますが、map
を使うことでコードが短くなり、より読みやすくなります。
ここまでがオプショナルに対するmap
の基本的な使い方です。これを活用することで、コードがシンプルになり、可読性も上がるので、ぜひ皆さんも試してみてください。これからも引き続きSwiftの勉強を進めていきましょう。それでは、また次回お会いしましょう。 映画作りというのは最近では新しい手法ですね。また、表情の再現が非常によくできています。たとえば、リブラリーの初期化を実写で行うケースもあります。
リブラリー初期化についてですが、条件付きで読み取りが可能な場合もあります。以前は読み取りが結構強かったのですが、初期化されたことで条件付けが少なくなったと思います。読者には初期化と読み取りの違いが少し分かりにくいかもしれませんが、個人的にはリブラリーの初期化が非常に重要だと思っています。
また、インシュライズのタイミングも重要です。コミュニティのゲームスタイルも、このインシュライズのタイミングによって変わることがあります。これには「サーベイシップス」と呼ばれる手法が関連してきます。例えば、マップの対応やオプショナルの話も関係してくるでしょう。
マップについてですが、今回のブログで紹介したマップを使用することもできますし、新たに使えるようになったライブラリーやスイッチのエクスプレッションを使っていくことも可能です。ただ、このエクスプレッションを使うときには、特定の仕様に対応する必要があるため、注意が必要です。
スイッチの場合も同じで、ケースによっては特定の処理を行う必要があります。一般的にマップを知っている人には肯定的な反応が多いと思います。これは特に奇抜な仕様ではなく、普通のメソッドがオプショナルに用意されているだけなので、多くの方には受け入れやすい提案ですね。
最近お話しした内容の中で、条件式で処理することや、初期化を遅らせるために let
に変えたりといった提案がありました。たとえば、お好み焼きの初期値として特定の値を持たせる方法についても、コード例を明記して誤解がないようにすることが大切です。
最後に、一つ余談ですが、特定の値を持つために初期化を遅らせることも可能です。この方法についてはよく検討し、場合によっては var
を使って後から値をセットすることが必要になるでしょう。このような書き方によって、初期化を避けて徐々に設定していくことが可能になります。 宣言、初期化、参照について話しました。個人的に遅れを感じている方もいますが、それは誰でも通る道ですね。初心者向けである方が理解しやすいと感じることもあります。
ブログでも書かれていますが、特にSwiftの場合、初期化を終えたら状態が確定するため、不安が減ります。コードを書く際にこういった不確定な要素を排除することで、他の考慮が不要になります。
Swiftの確定初期化は基本的なもので、余計な考慮が必要ないところがポイントです。確定初期化は多くのオブジェクト指向言語で当たり前のように使用されています。プロパティを宣言し初期化しない場合でも、イニシャライザで初期化のタイミングを遅らせることができます。しかし、実際に使用するときには初期化が確定されるので、安心して使えますね。
ここで重要なのは、Swiftのコンパイラが初期化のタイミングを確認し、必要な値が割り当てられていることを保証してくれることです。もし初期化していない場所があれば、コンパイル時にエラーメッセージが表示されます。
他の部分でも、例えばデータの参照などで、初期化が必要なものは必ず初期化される仕組みが重要です。この考え方は自律的なエリアであり、スコープ外に影響を与えません。
インスタンスを生成しただけではプロパティに値が何も入っていないことがあります。しかし、そのプロパティを使用するタイミングで初期化を行う必要があります。この点を意識することが重要です。
今回はここまでにしましょう。次回も引き続き、Swiftの初期化や他のポイントについて詳しく見ていきます。それでは、今回の勉強会を終わります。お疲れ様でした、ありがとうございました。