Locked History Actions

Diff for "scala/import"

Differences between revisions 2 and 3
Deletions are marked like this. Additions are marked like this.
Line 24: Line 24:
== trait === たとえprivateでもコンパイラに見えてしまうことに注意 ===

これはおそらくコンパイラのバグ。少なくとも意図しているわけでは無いと思われる。

{{{
class Foo {
  val field = 123
}
class Bar {
  private val field = 456
}
object Main {
  def main(args: Array[String]) {
    val foo = new Foo
    val bar = new Bar
    import foo._
    import bar._
    println(field) // reference to field is ambiguousというエラー
  }
}
}}}
Barのfieldはprivateであるにも関わらず、fieldという名前をFooのものかBarのものか決められないということ。
このエラーが出るので、例えば以下のようなことができない。

{{{
trait Logger {
  protected def info(s: String) { }
}

class Foo extends Logger {
}
class Bar extends Logger {
  def something() {
    val foo = new Foo
    
    import foo._
    info("something happen")
  }
}
}}}

結局はなんでもかんでもtraitにしない方が無難ということ。以下のようにした方がよい。
{{{
class Logger {
  protected def info(s: String) { }
}

class Foo {
  private val logger = new Logger
}
class Bar extends Logger {
  private val logger = new Logger
  def something() {
    val foo = new Foo
    
    import foo._
    info("something happen")
  }
}
}}}

import

オブジェクトのインポート

オブジェクトをインポートすることで、そのオブジェクトを指定しなくともメンバにアクセスできるよになる

class Foo {
  val field = 123
}
object Main {  
  def main(args: Array[String]) {
    val foo = new Foo
    import foo._
    println(field)
  }
}

結果は

123

たとえprivateでもコンパイラに見えてしまうことに注意

これはおそらくコンパイラのバグ。少なくとも意図しているわけでは無いと思われる。

class Foo {
  val field = 123
}
class Bar {
  private val field = 456
}
object Main {  
  def main(args: Array[String]) {
    val foo = new Foo
    val bar = new Bar
    import foo._
    import bar._
    println(field) // reference to field is ambiguousというエラー
  }
}

Barのfieldはprivateであるにも関わらず、fieldという名前をFooのものかBarのものか決められないということ。 このエラーが出るので、例えば以下のようなことができない。

trait Logger {
  protected def info(s: String) { }
}

class Foo extends Logger { 
}
class Bar extends Logger {
  def something() {
    val foo = new Foo
    
    import foo._
    info("something happen")
  }
}

結局はなんでもかんでもtraitにしない方が無難ということ。以下のようにした方がよい。

class Logger {
  protected def info(s: String) { }
}

class Foo { 
  private val logger = new Logger
}
class Bar extends Logger {
  private val logger = new Logger
  def something() {
    val foo = new Foo
    
    import foo._
    info("something happen")
  }
}