2

您能否解释一下为什么以下代码无法按预期工作。

演员没有打印消息

谢谢。

class Base {
  def f() = { "This is Base" }
}

class Sub extends Base {
  override def f() = { "This is Sub" }
}

case class myCase(x: Base)

import scala.actors._

object myActor extends Actor {

  def act()
  {
    loop {
      react {
        case myCase(x) => x.f()
        case msg => "unknown"
      }
    }
  }

  def main(args: Array[String]): Unit = {
    this ! myCase(new Base)
    this ! myCase(new Sub)
  }
}
4

1 回答 1

4

回答问题

该问题与继承或案例类无关(我已重新命名该问题以反映这一点)。代码不打印任何内容有两个原因:

  1. 因为您的代码实际上并没有对println! 代替:

    case myCase(x) => x.f()
    

    case myCase(x) => println( x.f() )
    
  2. 因为你没有开始你的演员。我认为如果演员是内部阶级,你的程序会更有意义:

    object myActor extends App {
    
      class MyActor extends Actor {
        def act() {
          loop {
            react {
              ...             // <-- You need to print stuff
            }
          }
        }
      }
    
      val a = new MyActor
      a.start()             // <-- You need to start it
      a ! myCase(new Base)
      a ! myCase(new Sub)
    }
    

建议:案例类和继承

但是,我建议在存在案例类的情况下使用继承是一个坏主意。我通常使用在特征中声明常见行为/状态的方法:

sealed trait Base {
  def f(): Unit
}

case class Sub() extends Base

为什么这是个坏主意?好吧,案例类为您提供的合同之一是对等价的严格定义(即 an equalsandhashCode实现)。在存在继承的情况下,这很可能会产生误导。也就是说,您的代码可能不会达到您的预期。考虑以下;

scala> abstract class Base { val x: Int }
defined class Base

scala> case class Sub(s: String) extends Base { val x = util.Random.nextInt(100) }
defined class Sub

现在,如果我创建 2 个实例...

scala> Sub("Hey")
res2: Sub = Sub(Hey)

scala> Sub("Hey")
res3: Sub = Sub(Hey)

它们是等价的

scala> res2 == res3
res4: Boolean = true

但他们没有相同的状态

scala> res2.x
res5: Int = 28

scala> res3.x
res7: Int = 15

请注意,我并不是说这是一个错误。我只是说这是一个您可能会发现您在代码中引入错误的区域,因为您已经假设案例类的任何状态都包含在其等效项中。

于 2012-04-30T10:53:46.687 回答