回答編集履歴

1 修正

_Kentarou

_Kentarou score 8289

2016/04/22 22:14  投稿

まず以下のサイトを一読することをオススメします。
[どこよりも分かりやすいSwiftの"?"と"!"](http://qiita.com/maiki055/items/b24378a3707bd35a31a8)
ryuuichi2014さんのコードを自分なりに書きなおしてみました。
コードを見るとわかると思いますが、「!」のマークが一切ありません。
「!」を変数の後ろに付けると強制的にnilでは無いと明示していることになります(Forced Unwrapping)、この場合値がnilだった時にアプリが落ちます。
「!」を変数の後ろに付けると、強制的にnilでは無いと明示していることになります(Forced Unwrapping)、この場合値がnilだった時にアプリが落ちます。
コードの中でnilのチェックはしているので問題ないのですが、Optional Bindingというしくみを使うとnilで無い場合のみ値を取り出せる機能があります。(if let ~)
コードの中でnilのチェックはしているので問題ないのですが、Optional Bindingというしくみを使うとnilで無い場合のみ値を取り出しif文の中を実行する機能があります。(if let ~)
Optional Bindingで取り出した値はnilではないのでその後「!」の出番はありません。
提示されているコードで問題があるとすると以下の部分だと思います。
strはnilではなく、空文字だった場合は”0”が入って言いますが"a"などの文字が入った場合intNumがnilになってしまうので、その後の計算で落ちます。
極力「!」を使わない様に記述することで更に安全なコードが書けるかと思います。
```swift
let intNum:Double! = Double(str!)
let an:Double! = intNum! % 2
```
```swift
import UIKit
class ViewController: UIViewController {
   
   @IBOutlet weak var inputText: UITextField!
   @IBOutlet weak var anser: UILabel!
   
   @IBAction func inButton(sender: AnyObject) {
       
       // inputText.textがnilの場合以下の処理は行わないように早期にreturnします
       guard let str = inputText.text else { return }
       // 以下strにnilが入っていないことは保証されています。 
   
       // ちょっと強引ですがstrが空文字か比較して空文字の場合"0"を代入しています
       if let intNum = Double(str == "" ? "0" : str) {
           
           // この中のintNumもnilで無いことが保証されています。
           // nilでは無いのでそのまま計算します。
           let an:Double = intNum % 2
           
           // 三項演算子でan == 0がtrueかfalseにより代入する値を分けます。
           anser.text = an == 0 ? "偶数" : "奇数"
       }
   }
   
   override func viewDidLoad() {
       super.viewDidLoad()
   }
}
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る