がばがばscala独学 - トレイト(3)
はじめに
下記のテキストを通して、基本的な書き方を学びつつ、個人的に気になったことを検証していくメモ代わりです。
https://dwango.github.io/scala_text/basic.html
本当にありがとう、dwango様・・・
トレイトの初期化順序
- ざっくりまとめ
- 初期化順序によっては、初期化されていない変数が出てくる
- 初期化できていない原因となるtraitを改善することが一番である
落とし穴
-
初期化順序によっては機能しない変数が出てくる
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val foo: String }
trait B extends A { val bar = foo + "world" }
class C extends B {
val foo = "hello "
def printBar(): Unit = println(bar)
}
(new C).printBar()
// Exiting paste mode, now interpreting.
nullworld
defined trait A
defined trait B
defined class C
nullworld
となって、 hello world
と期待した結果となっていない
-
lazy
を使用して処理を遅延させる
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val foo: String }
trait B extends A { lazy val bar = foo + "world" }
class C extends B {
val foo = "hello "
def printBar(): Unit = println(bar)
}
(new C).printBar
// Exiting paste mode, now interpreting.
hello world
defined trait A
defined trait B
defined class C
初期化が実際に使われるまで遅延される
-
デメリット
- 通常の変数定義より若干処理が重い
- 複雑な呼び出しでデッドロックが発生
-
defによる定義
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val foo: String }
trait B extends A { val bar = foo + "world" }
class C(val foo:String) extends B {
def printBar(): Unit = println(bar)
}
(new C("hello ")).printBar()
// Exiting paste mode, now interpreting.
hello world
defined trait A
defined trait B
defined class C
- デメリット
- 毎回定義しなければならない点
-
事前定義(Early Definitions)を使う
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val foo: String }
trait B extends A{ val bar = foo + "world" }
class C extends {
val foo = "hello"
} with B {
def printBar(): Unit = println(bar)
}
(new C).printBar()
// Exiting paste mode, now interpreting.
helloworld
defined trait A
defined trait B
defined class C
根本的には trait B
に問題があるため、 trait B
を修正したほうがいい
- 初期化順序によっては、初期化されていない変数が出てくる
- 初期化できていない原因となるtraitを改善することが一番である
初期化順序によっては機能しない変数が出てくる
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val foo: String }
trait B extends A { val bar = foo + "world" }
class C extends B {
val foo = "hello "
def printBar(): Unit = println(bar)
}
(new C).printBar()
// Exiting paste mode, now interpreting.
nullworld
defined trait A
defined trait B
defined class C
nullworld
となって、 hello world
と期待した結果となっていない
lazy
を使用して処理を遅延させる
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val foo: String }
trait B extends A { lazy val bar = foo + "world" }
class C extends B {
val foo = "hello "
def printBar(): Unit = println(bar)
}
(new C).printBar
// Exiting paste mode, now interpreting.
hello world
defined trait A
defined trait B
defined class C
初期化が実際に使われるまで遅延される
デメリット
- 通常の変数定義より若干処理が重い
- 複雑な呼び出しでデッドロックが発生
defによる定義
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val foo: String }
trait B extends A { val bar = foo + "world" }
class C(val foo:String) extends B {
def printBar(): Unit = println(bar)
}
(new C("hello ")).printBar()
// Exiting paste mode, now interpreting.
hello world
defined trait A
defined trait B
defined class C
- デメリット
- 毎回定義しなければならない点
事前定義(Early Definitions)を使う
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait A { val foo: String }
trait B extends A{ val bar = foo + "world" }
class C extends {
val foo = "hello"
} with B {
def printBar(): Unit = println(bar)
}
(new C).printBar()
// Exiting paste mode, now interpreting.
helloworld
defined trait A
defined trait B
defined class C
根本的には trait B
に問題があるため、 trait B
を修正したほうがいい
Author And Source
この問題について(がばがばscala独学 - トレイト(3)), 我々は、より多くの情報をここで見つけました https://qiita.com/chara06ken/items/2702953b1f425d7ca6d1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .