質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

3回答

4828閲覧

【Swift3】引数の値がnilだった場合、0を代入したいけど、できない

RagnAnet1373

総合スコア69

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/04/18 00:10

###前提・実現したいこと
Swift3 Xcode8にて
今回、数値入力欄があり計算ボタンを押した時に、入力欄の中身をチェックして
それが空(nil)だった場合「0」を、それ以外はそのまま代入をすることを実現したいです。

###発生している問題・エラーメッセージ

nilでも関数の判定を行いたい時に次のようなエラーメッセージがでます。 fatal error: unexpectedly found nil while unwrapping an Optional value

###該当のソースコード

Swift

1@IBOutlet weak var sumprice: UITextField! 2@IBOutlet weak var member: UITextField! 3 4 5var sum:Double? = numCheck(sumprice.text!) 6var members:Double? = numCheck(member.text!) 7 8func numCheck(_ number:String)->Double 9{ 10 let num:String? = number 11 var answer:Double? 12 13 if(num == nil) 14 { 15 answer = 0 16 } 17 else 18 { 19 answer = Double(num) 20 } 21 return answer 22}

###補足情報(言語/FW/ツール等のバージョンなど)
冒頭でもお伝えしておりますが、
Swift3 Xcode8の環境で開発を行なっております。
Swiftを触り始めてまだほんの少ししか経っておらず、知識不足で粗だらけのプログラムですがどうかご教授のほどよろしくお願い致します

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/04/18 00:24

numberが何の時にどこでエラーが出るのでしょうか?
guest

回答3

0

変数の初期化時に他の変数を値を使用することはレイジープロパティ(lazy stored property)にする必要があります。
※ 以下の例だと最初からTextFieldに値が入っていることになりますが、、、

swift

1lazy var sum:Double? = self.numCheck(self.sumprice.text!) 2lazy var members:Double? = self.numCheck(self.member.text!)

その上でメソッドを以下の様にすると良いと思います。

swift

1func numCheck(_ number:String)->Double 2{ 3 // 引数がString型なのでnumの型をわざわざOptionalにする必要は無いです 4 let num:String = number 5 6 // answerもDouble型しか入らないのでOptionalにする必要は無いです 7 var answer:Double 8 9 if let value = Double(num) { 10 11 answer = value 12 } else { 13 answer = 0 14 } 15 16 return answer 17}

投稿2017/04/18 00:25

編集2017/04/18 00:27
_Kentarou

総合スコア8490

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

RagnAnet1373

2017/04/18 01:22

回答ありがとうございます。 プログラムがスムーズに動くようになりました。 ただ、lazyプロパティについて少し調べてみたのですが、値などを入れる際に一度だけ処理を実行したいという時に使うものと拝見致しました。 詳細に書くことを忘れており申し訳ありません。今回このプログラムを繰り返し使用したいと考えています。 そうすると書いてくださったプログラムですと、どうしてもそれ以降、値を変更できなくなってしまいました。この場合、lazy以外のプロパティを使用したり、プログラムそのものを変更する必要があるでしょうか
guest

0

自己解決

swift

1 func checkNum(_ number: String?)->Double 2 { 3 let num:String? = number! 4 var numAnswer:Double 5 6 if let value = Double(num!) 7 { 8 numAnswer = value 9 } 10 else 11 { 12 numAnswer = 0 13 } 14 15 return numAnswer 16 }

関数の引数をOptional型にすることで、nilでも反応するようになりました。

ご教授していただいた上記コードの修正したものです

swift

1func checkNum(_ number: String?) -> Double { 2 var numAnswer: Double = 0 3 if let num = number { //※ここが重要 4 if let value = Double(num) { 5 numAnswer = value 6 } 7 } 8 return numAnswer 9}

ご教授してくださったfuzzballさん、_Kentarouさん本当にありがとうございました!!!

投稿2017/04/18 04:45

編集2017/04/18 07:22
RagnAnet1373

総合スコア69

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/04/18 05:03

これ、numberがnilだと落ちるでしょ?
RagnAnet1373

2017/04/18 05:31

Xcode8のシミュレータ上では動いたのですが、実機になるとこれは落ちてしまうのでしょうか・・・?
fuzzball

2017/04/18 05:39

print(checkNum(nil)) こうやると落ちませんか?
RagnAnet1373

2017/04/18 05:50

ご指摘された通り 書かれたプログラムを打ち込んで計算ボタンを押すと if let value = Double(num!) この時に止まって fatal error: unexpectedly found nil while unwrapping an Optional value とまたエラーメッセージが出ました。 これはif文の書き方に問題がありますか?それとも引数などがまだ間違えてるのでしょうか・・・?
fuzzball

2017/04/18 06:13 編集

回答のコードを修正してみます。(インデントが潰れるのでXcodeにコピペしてから眺めて下さい) func checkNum(_ number: String?) -> Double { var numAnswer: Double = 0 if let num = number { //※ここが重要 if let value = Double(num) { numAnswer = value } } return numAnswer }
RagnAnet1373

2017/04/18 06:23

回答してくださったコードを書くとうまくいきました! ありがとうございます! 回答したコードを先ほどまで模索していると nilのnumberを型変換しようとしているところでエラーが出ていたのでこれをどうすればいいんだという状態に陥ってました。 先ほどまでのコードと見比べると numAnswerの初期値を0で確定しているところ、 条件式でいきなりnumber変換して入るわけではなく、呼び出し時のnumberをnumに入れて判定を行なっているというところが違う点として見られます。 if文の点で、numberをlet型のnumという定数に入れて判定を行なっているように見えますが、なぜこのようにするとうまくいくのでしょうか・・・。ご教授していただけると今後のためにもすごく助かります・・・。
fuzzball

2017/04/18 06:26

あなたのコードの、 if let value = Double(num) { これと同じことをしているのですが、あなたはなぜこういう風に書いたのですか?
RagnAnet1373

2017/04/18 06:45

言い訳になってしまいます、大変申し訳ございません。 先ほど_Kentarouさんにお教え頂いたコードにif文があり、そのコードを見て 「このような判定の仕方がswiftではできるのか」と思い、この通りできるなら値があったら 直下のプログラム、値がなかったらelseのところを通るものだと思って書いていました。
fuzzball

2017/04/18 07:04

判定だけではなくアンラップもしています。(Optional Bindingといいます) 繰り返しますが、Optional型の勉強をして下さい。 「swift optional」でググれば記事はたくさん見つかります。 なるべく新しい記事を読みましょう。また、一つの記事だけではなく複数読みましょう。
RagnAnet1373

2017/04/18 07:18

ご指摘ありがとうございます! 始めたてで難しいことは多いですが、オプショナル型は、お教えいただいた記事など様々なところを利用して勉強をし、はやく使いこなせていけるように頑張っていきたいと思います! 繰り返しになりますが、本当にありがとうございました!
guest

0

numCheck()に飛ぶ前のsumprice.text!の時点でエラーが出ているのだと思います。
もう少しOptional型の勉強をして下さい。

投稿2017/04/18 00:29

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

RagnAnet1373

2017/04/18 01:12

回答ありがとうございます。 わかりました、著書を購入したりネットを見たりしてもう少し勉強をしてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問