🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

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

Q&A

解決済

2回答

1706閲覧

Swift4にてletへの再代入は不可のはずですが入門書にして代入しているように思えるのですがなぜ代入できるのでしょうか?

hironante

総合スコア8

Swift

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

0グッド

1クリップ

投稿2019/09/23 16:04

Swiftの入門書にてSwift4の学習をしていますが、疑問な点があり
ご教授頂ければと思います。

書籍中のクイズアプリの作成を勉強しているのですが下記のようなコードがあり
letの使い方に疑問があります。
letのプロパティにおいて代入が不可であると認識しているのですが
書籍掲載の下記のコードではcsvを1行ずつ読み込み、questionDataに再代入しているように思えます。
varではなくletとなっているのはなぜでしょうか?
よろしくお願いします。

全部掲載するのはまずいかと思いますので一部抜粋

var questionDataArray = [QuestionData]() // csvStringDataには問題文がカンマ区切りで入っている。 // 問題1,選択肢1,選択肢2,正解番号 // 問題2,選択肢1,選択肢2,正解番号 // みたいな感じ csvStringData.enumerateLines(invoking: { (line, stop) in let questionSourceDataArray = line.components(separateBy: ",") // 問題データを格納するオブジェクトを作成 let questionData = QuestionData(questionSourceDataArray: questionSourceDataArray) // 問題を追加 self.questionDataArray.append(questionData) // 問題文の番号を設定 questionData.questionNo = self.questionDataArray.count })

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

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

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

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

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

kagilinn

2019/09/23 17:56

「どこで」再代入しているように思えますか? コード中にコメントなどで示して頂けると幸いです.
hironante

2019/09/24 01:34

この部分になります let questionData = QuestionData(questionSourceDataArray: questionSourceDataArray)
guest

回答2

0

ベストアンサー

maisumakunさんのおっしゃる通り、再代入は行なっていません。
スコープ内で、同じ変数名を再帰的に使っているだけなので、
一回一回のループ処理で、変数の有効範囲(スコープ)は消滅しています。
よって、let宣言子によってループ都度新たな変数が定義されている状態です。

ただし、配列変数questionDataArrayに追加されているため、メモリから解放されているわけではなく、
その都度違う変数として、格納されている状態です。

変数のスコープに関して、調べ、勉強されると、
理解できるかと思います。

投稿2019/09/24 00:51

miyabi_takatsuk

総合スコア9555

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

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

hironante

2019/09/24 01:46

回答ありがとうございます。 invokingがループ処理されるのでその都度スコープが消滅して再定義されるということですね。 僕は勘違いしていて invoking: { // このスコープ内でループ処理が行われていると思っていました。 } この認識で間違っていないでしょうか?
miyabi_takatsuk

2019/09/25 04:38 編集

認識合っていると思います。 今回のメソッドは、invoking引数に代入されたクロージャ関数自体が再帰的に呼び出されていると思われるので、{}のブロック(invoking)が呼び出されるたびにそのスコープは発生、消滅を繰り返します。 for var i = 0; i < 10; i++ { let aaa = i; } とした時、aaaが再代入にならずエラーが起きないのと同じです。 スコープは基本的に{}のブロック内で完結される、ということです。
hironante

2019/09/25 07:36

miyabi_takatuk様 すごく分かりやすく教えて頂きありがとうございます。 すっきりしました。
guest

0

書籍掲載の下記のコードではcsvを1行ずつ読み込み、questionDataに再代入しているように思えます。

再代入は行っていません。代入したオブジェクトを破壊的に変更しているだけです。

投稿2019/09/23 22:11

maisumakun

総合スコア145975

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

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

hironante

2019/09/24 01:48

回答ありがとうございます。 miyabi_takatsukさんへコメントしたように僕は基本的なことを理解していなくて下記のように思ってました。 invoking: { // このスコープ内でループ処理が行われていると思っていました。 }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問