Kotlin
1var allByDefault: Int? // エラー:明示的なイニシャライザが必要 2val simple: Int? // エラーは出ない。コンストラクタ内で初期化が必要
valの場合はコンストラクタ内で初期化すればいいのに対して、
varの場合はコンストラクタ内での初期化ではいけないのですか?
ご存知のかた教えてください
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
kotlinはリファレンスをちょっと読んだだけであんまり自信は無いのですが、
リファレンスを読んだ感じでは、クラスのプロパティとしてのvar
とval
の違いは、
var
はミュータブルでデフォルトのセッターとゲッターを持ちval
はイミュータブルでデフォルトのゲッターを持ち、セッターは認めない
で、どちらも明示的に初期化が必要
なので、val simple: Int?
も初期化をしていないとエラーが出ます。
fun main(args: Array<String>) { class Test() { // どちらも『error: property must be initialized or be abstract』が出る var allByDefault: Int? // エラー val simple: Int? // エラー } }
どちらもプライマリコンストラクタで初期化が出来ます
kotlin
1fun main(args: Array<String>) { 2 class Test(num: Int) { 3 var allByDefault: Int? = num // OK 4 val simple: Int? = num // OK 5 } 6}
イニシャライザで初期化してもOK
kotlin
1fun main(args: Array<String>) { 2 class Test() { 3 var allByDefault: Int? 4 val simple: Int? 5 init { 6 allByDefault = 0 // OK 7 simple = 1 // OK 8 } 9 } 10}
ちなみに、val simple: Int? // エラーは出ない。コンストラクタ内で初期化が必要
と記述されているサイトが見つけられなかったのですが、どこのサイトを参考にしたのでしょうか?
投稿2017/05/26 02:46
編集2017/05/26 02:48退会済みユーザー
総合スコア0
0
ベストアンサー
IntelliJ IDEA Community Edition 2017.2でやってみました。(Kotlinを開発したJetBrain社のIDEです)
初期化についてはvalもvarも同じだと思います。どちらもコンストラクターや初期化ブロック内(init{})で初期化すればエラーにはなりませんでした。
Javaでは非finalなフィールドは値を初期化しなくても許されますが、Kotlinではそれは許さないようです。それはプロパティーをabstractと宣言できる言語仕様に起因すると思います。
abstractでないプロパティーは必ずプロパティーの宣言、コンストラクター、初期化ブロックのいずれかで値が与えられなければならない。一方abstractならそのいずれでも値を与えてはならない。
そういう意味なのだろうと思います。シンプルです。
余談:
ところでprimary constructor(最も基本的なコンストラクター)を以下のように書けることをご存知と思います。
kotlin
1class A(var a: Int, val aNumber: Int) { 2 val doubleNumber = aNumber * 2 3 ... 4}
Scalaなんかでもそうですね。Javaから入るとちょっと戸惑いますが、このスタイルは合理的な気がします。なぜなら、インスタンスを作る際の(最も基本的なコンストラクションでの)パラメーターがクラス定義全体のスコープから見えるため、プロパティーの宣言と初期化を一々分離することなく単純に書けることが多いからです。
最初のころ、クラスの属性(フィールドあるいはプロパティ)がクラス宣言の本体の内側に同じインデント位置で並んでいるスタイルに慣れていたので、クラス宣言の場所に属性の一部が並ぶことに若干の違和感がありました。フィールドに対してJavaDocを丁寧に記述しているようなケースでは少々気持ち悪い感じにもなります。
Kotlin
1class A( 2 /** 3 * A variable for this class. 4 */ 5 var a: Int) { 6 /** 7 * A value for this class. 8 */ 9 val c: Int = 0 10 ... 11}
しかし、慣れてくるとインデントのずれによる少々の気持ち悪さよりも「名前や型の宣言とその値をすぐ近くに書けたり、冗長な書き方をせずに済む」ことの方が本質的に重要であると感じるようになりました。こうした点もKotlinがbetter javaたらんとする点の一つだと思います。
余程複雑な依存関係を持つプロパティーでない限りコンストラクターの中で書かなければならないケースはむしろ少ないと思います。そういう観点(どこがbetter javaなのか)の方を考えてみた方がよいのではないでしょうか?
投稿2017/05/26 03:37
総合スコア18394
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
うーん、エラー出ないけど‥。
kotlin
1class Hoge { 2 var allByDefault: Int? 3 constructor() { 4 allByDefault = 9999 5 } 6} 7 8println(Hoge().allByDefault) 9//=> 9999
投稿2017/05/26 02:12
編集2017/05/26 02:51総合スコア16731
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/05/28 20:57
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/05/28 20:56