- 更新日: 2020年07月10日
- 公開日: 2020年03月13日
【Swift入門】Swift文法を楽しく理解しよう - オプショナル型編
Swiftの学習をはじめて、 XCode をさわり始めるとよく目にするようになる ! のマーク。
今回は、この ! や ? についてご説明します。
【Swift入門】Swift文法を楽しく理解しよう - オプショナル型編
!マーク
XCode で UI部品とコードを接続すると ViewController.swift に登場してくる以下のコード。
@IBOutlet var text: UILabel!
@IBOutlet var textView: UIImageView!
学習初期の段階では、このコード末尾についている ! マーク、あまり気にかけていない方も多いと思います。しかしこの ! マーク、実はすごく重要で XCode でアプリを作る上では必須項目。
例えば、この ! マークを分かっていないと以下のようなエラーを見過ごすことに。
- 入力欄を設けたのに 未入力 のまま投稿される
- 計算ができない
- print文で出力すると optional() という文字も一緒に表示される
実際にこんなことが起きたら困りますよね。それでは ! について詳しく見ていきたいと思います。
オプショナル型
UI部品をコードに接続すると登場してくる @IBOutlet var text: UILabel! の ! マークは、オプショナル型を示すマークになります。オプショナル型、これはデータ型の一種でいわば Int(数値型) や String(文字列型) の親戚。
! を使うことで、 変数が 無(nil) でもプログラムエラーを引き起こさず、正常に扱えるようになります。コードとしては、こんな感じ。
コード | 結果 |
|
1行目の var a:Int! は、変数 a をオプショナル型として宣言。これで変数 a が 無(nil) でもプログラムはエラーを出すことなく、稼働してくれます。逆にオプショナル型を外すとこのような形に。
コード | 結果 |
|
この場合エラーが出て、プログラムを実行できません。このようにオプショナル型を使うと 無(nil) を受け入れることができるように。ちなみにオプショナル無しで変数 a に値を与える時はこんな感じ。
コード | 結果 |
|
オプショナル型のメリット
変数が 無(nil) を受け入れられる
変数が 無(nil) といってもチョットイメージにし難いかもしれませんが、要は入力欄に 空欄 があっても OK ということ。空欄で身近なものといえば、
- アンケートフォーム
- ユーザー情報の項目
- 注文フォームの項目
- チャットの追加機能(画像添付など) etc
普段何気なく利用しているアプリの入力欄、必須項目じゃなかったら空欄でいきますよね。こうした空欄データを受け入れるためにオプショナル型が必要という訳です。
オプショナル型は、 Swift以外の Java や Python、 Ruby など他の言語にもあり、決して特別なものではありません。書き方さえ違えど、プログラミングの基礎になりますので頑張って理解しておきましょう。
XCodeにおけるオプショナル型
XCode で UI部品を接続すると、必要に応じて自動的にオプショナル型になり、人的な入力ミスを防いでくれます。例えば、 UI部品 Text Field を ViewController.swiftに接続すれば @IBOutlet var textAdd: UITextField! というコードが自動生成。この他にも Label や Text View など部品に応じてオプショナル型を自動生成。
一見すると便利そうですが、実は不便な点も。先ほど ToDoリストのアプリを作ってみましたが、普通のプログラム処理では ToDo項目が 空欄 でも画面に 空欄が反映されて、すき間ができます。
ToDo App Erorr Type の xcodeproj file
これは UI部品として追加した Text Field が textAdd: UITextField! とオプショナル型になっているため、 無(nil) つまり 空欄も受け入れてしまう仕組み。XCodeで textAdd: UITextField! の ! を削除すればエラーになりますので、他の方法で空欄の受付を阻止する必要が出てきます。
結果的には、
if text == "" {
return
}
と空欄の場合はテキストを追加するのではなく、 return で戻しちゃえば 空欄入力をうまくかわすことが可能に。詳しくは実際にシュミレーションして確かめてみて下さい。
XCodeのオプショナル型を処理した例
! と ? の違い
XCodeを使っているとはじめの内はどちらかというと ? より ! の方をよく見かけます。どちらも 無(nil) を受け付けるオプショナル型ですが、違いはチョット分かりにくいですね。実際にコードを並べてみると雰囲気がつかめると思いますので、まずはコードを参照ください。
var a:String? = "hello"
print(a)
var aa:String? = "hello"
print(aa!)
var b:String! = "hello"
print(b)
var c:String = "hello"
print(c)
print(a,b,c)
//print(a+b+c)
print(a!+b+c)
結果
一番最初の
var a:String? = "hello"
print(a)
は、 hello をオプショナル型にセットしていますが、 XCodeによって String? から Any型 に強制的に変更されています(黄色の注意喚起文)。しかし、2番目のコードにあるように aa をアンラップ( aa! )すると XCodeは String? を処理してくれていますね。
<< アンラップとラップ >>
? や ! を使った場合、 print文を見てみると optional("hello") という風に自動的に optional() が追加。 ? を使っている場合、これは "hello" がラップされている状態を示し、通常の変数と一緒に扱うことはできません。アンラップの方法はいくつかありますが、よくみる方法は ! を用いた手法。
var a:String? = "hello"
print(a!)
と print(a) 部分を a! にするとアンラップ。
? のオプショナル型に対して ! は、ラップされていないので XCodeもエラーを出しません。
3番目のコード
var b:String! = "hello"
print(b)
これらの結果から文字列を扱う時、 変数を ? で設定した場合は、必ずアンラップ処理を加える必要があります。
エラーになるコード
print(a+b+c)
エラー回避のコード
print(a!+b+c)
print() など最終処理で変数を扱う時、その変数がラップされたものかどうか、プロジェクトが大きくなると悩みますよね。そのため XCodeでは ? より ! の方がエラー抑制のために自動表記されるのではないかと考えます。
上記コードは String型 でサンプリングしましたが、 Int型でも同じ結果です。
! と ? の簡易比較表
optional型 | ! | ・ラッピングされていない |
\Webサイト担当者としてのスキルが身に付く!!/
まとめ
今回は Swift および XCode で登場してくるオプショナル型の基本的なことをご紹介しました。実際にアプリを作っていくと「オプショナル型、奥が深いなぁ」と気付き、ネットで オプショナル型 を検索すると様々な角度でテストしたり解説している様子が見受けられます。 はじめから理屈で固めていこうと思うと整理つきにくいので、まずは実際にコードを書いて、試作アプリを作って、オプショナル型を体験することをオススメします。
「iPhoneアプリ作ってみたいけど、 XCodeの使い方がよくわからないな」「参考書通りにやっているんだけどエラーが消えない」と悩んでいる方、 iPhoneアプリ開発のエンジニアが所属するプログラミグスクール CodeCamp を頼ってみませんか?無料相談や無料体験を通じて、独学でいくか、教えてもらうか、の判断材料になると思いますよ。
- この記事を書いた人
- オシママサラ