LoginSignup
0
0

More than 5 years have passed since last update.

がばがばscala独学 - トレイト(3)

Posted at

はじめに

下記のテキストを通して、基本的な書き方を学びつつ、個人的に気になったことを検証していくメモ代わりです。
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 を修正したほうがいい

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0