Scala演员显然没有收到消息

时间:2012-04-30 10:46:47

标签: scala pattern-matching

请您解释一下为什么以下代码没有按预期工作。

演员没有打印消息

感谢。

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)
  }
}

1 个答案:

答案 0 :(得分: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)
    }
    

  3. 建议:案例类和继承

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

    sealed trait Base {
      def f(): Unit
    }
    
    case class Sub() extends Base
    

    为什么这是一个坏主意?好吧,案例类给你的一个合同是等价的严格定义(即equalshashCode实现。在存在继承的情况下,这可能是误导。也就是说,您的代码可能无法达到预期效果。请考虑以下事项;

    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
    

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