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

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

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

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

Q&A

解決済

1回答

737閲覧

SWIFTの構造体やクラスで初期化をする理由がわかりません

pegy

総合スコア245

Swift

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

0グッド

0クリップ

投稿2020/07/24 07:05

全ての言語に共通することかもしれませんが、今Swiftの構造体やクラスを勉強していますがイニシャライザを定義することで初期化する意味がまだピンときません。

こちらの投稿でイニシャライザが存在する理由は読み解くことができたのですが、そもそもなぜ値型の構造体や参照型のクラス初期化をしなくてはいけないケースが出てくるのでしょうか?

例えばこの様なqiitaの投稿でcard構造体を定義していますがイニシャライザは定義されていませんが、特に不便がない様に思えます。

なぜ、そもそも初期化をするのか、初期化しなければどの様な不便が起きるのかという観点からご教示いただけますでしょうか?

よろしくお願い申し上げます。

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

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

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

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

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

TsukubaDepot

2020/07/24 07:41

逆に、初期化しない場合の問題点を考えてみてはいかがでしょうか。 初期化しないでアクセスした場合、どのような値が出てくると想像できますでしょうか。
pegy

2020/07/24 08:14 編集

構造体(値型)であれ、クラスで(参照型)あれインスタンスを生成する際に let yobidashi = kozotaidesu(Int:10, Int: 20) let yobidashi = classdesu(Int:10, Int: 20) インスタンス側のプロパティだけに10や20が格納されるので、構造体やクラスそのものの値には影響がない様な直感があります。 class classdesu { let classprop: Int =10; //他の処理 } print(classdesu.classprop) の様に引数で値をとらない場合、そもそもクラスや構造体側でプロパティ値を指定していて、それを固定して利用したいため、初期化も何も常に値は固定であるという感覚を持っています。 これらの解釈自体がずれていたら誠に申し訳ございません。
TsukubaDepot

2020/07/24 08:17

「インスタンス側のプロパティだけに10や20が格納されるので、構造体やクラスそのものの値には影響がない」という解釈がイメージできないのですが、たとえばどのような状況を考えていらっしゃるのでしょうか。
pegy

2020/07/24 08:53

クラスは設計図でインスタンスはクラスを実体化したものと認識しております。 したがって、 let yobidashi = classdesu(Int:10, Int: 20) においては、設計図であるclassdesuは10や20というプロパティは知らず、実体側であるyobidashiインスタンスがそのプロパティとして10や20を知っているというイメージです。 よろしくお願い申し上げます
TsukubaDepot

2020/07/24 09:04

「設計図であるclassdesuは10や20というプロパティは知ら」ないので(正確には「個々のプロパティに代入する値を知ら」ない)、「実体側であるyobidashiインスタンス」を作るときに「10や20という値で初期化」しなければいけないのはご理解いただいていると思います。 しかし、そうなるとご質問の意図である「初期化をする理由がわかりません」が理解し難いのですが、どこに悩まれているのでしょうか。
pegy

2020/07/24 09:23

>「実体側であるyobidashiインスタンス」を作るときに「10や20という値で初期化」しなければいけないのはご理解いただいていると思います。 ここがおそらく理解できておりません。 例えば変数に値を格納する場合、 let hoge:string = "1st" で終わる作業で、ここで何かを初期化するという概念はない(それとも私が気付いていない)と思います。 そこで例えば、以下の記事に https://www.sejuku.net/blog/34191 class SampleClass { //変数の定義 var num = 0 var str1 = "" var str2 = "" //イニシャライザ // init(){ // self.num = 100 // self.str1 = "Samurai" // self.str2 = "Engineer" // } } let inst = SampleClass(); print(inst.num) で問題なく0が出力されます 一方で class SampleClass { //変数の定義 var num = 100 var str1 = "" var str2 = "" //イニシャライザ // init(){ // self.num = 100 // self.str1 = "Samurai" // self.str2 = "Engineer" // } } let inst = SampleClass(); print(inst.num) でも同じ様に100が出力されます。 ではなぜinit(){}が必要であるのか?というところが疑問でございます。
TsukubaDepot

2020/07/24 09:36

> ではなぜinit(){}が必要であるのか?というところが疑問でございます。 端的に言えば、「宣言時にすべてのプロパティが初期化(何らかの値が代入)されているのでイニシャライザ(あえて日本語化すれば「初期化子」)が必要ない、ということです。 逆に、何らかの値を一つでも代入していないクラスはイニシャライザが必須です。構造体は多少振る舞いが異なり、自分でイニシャライザを書く必要はないのですが、インスタンスを生成するときには初期化されていない変数についてすべて初期化を行う必要があります。 いま手元に資料がないのでより正確なことは言えないのですが、以前お勧めした下記の書籍 >(参考文献) >詳解 Swift 第5版 >著者 萩原剛志 >発行者 SBクリエイティブジャブ式会社 には、構造体、クラスに関するイニシャライザの解説が詳しく載っていると思いますので、まずはそれを読み直されてはいかがでしょうか。 例として提示されたリンクの内容はかなり怪しいので(著者が説明できない部分をあえて濁している感じがあるので)参考にしない方がいいかと思います。
TsukubaDepot

2020/07/24 09:46

いま改めて参考にされたリンクを見ましたが、やはり例示がおかしいというか、イニシャライザの意味が感じられない例しか出していないようです。 イニシャライザで決まった値を代入することはできますが、それだとイニシャライザのメリットがありません。イニシャライザのメリットの一つは、インスタンスを生成するときに、プロパティの値を動的に決めることができる点があるかと思います。 たとえば、 let a = Int(2) とすれば、Int 型で初期値が「2」のインスタンスが生成されますし、 let a = Int(3) とすれば、Int 型で初期値が「3」のインスタンスが生成されます。 もし、このように動的に値を決めることができない(初期化できなければ) var a = Int() a = 3 と後から値を代入しなおす(初期化しなおす)処理が必要になり、煩雑になってしまいます。 また、インスタンスを初期するにあたって「最低限指定しなければいけない値」が分かっていなければ(つまり、イニシャライザの引数として指定されていなければ)、インスタンスを生成後、自分でどのプロパティに値を代入しなければならないのかも把握することができません。 さらには、初期化しなければ使いことができないメソッドを、あるプロパティの初期化前に呼び出してしまうとその時点でエラーとなってしまいます。こうなってしまうと、もはやどこに根本的なエラーがあるのか把握することすら困難になってしまいます。
pegy

2020/07/24 10:17

覚えてくださっていて、ありがとうございます。まさに参考文献の構造体の箇所にイニシャライザを読んでいて、道に迷ってしまいました。読み込みがまだまだ足りないのかもしれません。 初期化というのは代入を値するという読み替えることができるのですね、。 以下の様にプロパティを値を動的に決めることができるのが直感的に理解できました。もちろん、これはそれだけでは意味がなく、ここで動的に指定したプロパティをインスタンスメソッド等で利用したりすることで意味があることなのかもしれません。 class Bar { var a: UInt8 init(a: UInt8) { self.a = a} } let inst = Bar(a:100); print(inst.a) 一方で >何らかの値を一つでも代入していないクラスはイニシャライザが必須です。構造体は多少振る舞いが異なり、自分でイニシャライザを書く必要はないのですが、インスタンスを生成するときには初期化されていない変数についてすべて初期化を行う必要があります。 については、なぜそうなのかというのが直感的にはわからないのですが、(確かに値も代入していないクラスのプロパティを定義すること自体が意味がないのですが)(コンパイル上の理由?)これは引き続き調べてみようと思います。 ありがとうございます。
TsukubaDepot

2020/07/24 10:21

イニシャライザの振る舞いは結構複雑(のように感じる)ので、最初から全てを理解するのも大変かと思います。 よく使う ViewController もクラスなのですが、そこには明示的なイニシャライザがないので、イニシャライザの必要性も感じられないのも誤解の理由かもしれません(イニシャライザがない代わりに、初期値が代入されていないプロパティがあるとコンパイルエラーになる)。 この辺りはいろいろ試されてみて、実感されるのが一番いいのではないでしょうか。
TsukubaDepot

2020/07/24 10:22

とりあえず、一旦落ち着きそうであれば、自己解決のような形で質問を閉じていただいてもよろしいでしょうか。 お手数をおかけしますが、よろしくお願いします。
pegy

2020/07/24 10:47

初心者のわかりづらい質問にお付き合いをいただき誠にありがとうございます。 本当に心から感謝を申し上げます。 よろしくお願い申し上げます。
guest

回答1

0

自己解決

上記の質問への追記・修正の依頼において、解決したため、自己解決としてCloseさせていただきます。

投稿2020/07/24 10:48

pegy

総合スコア245

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問