2009-07-27 3 views
4

저는 스칼라를 처음 사용합니다. 배우를 배울 때, 나는 데프의 한 줄을 저장하도록 확장을 시도 : 확장 스칼라 배우

import scala.actors.Actor 
import Actor._ 
class Actoo(actoo: =>Unit) extends Actor { 
    def act() {actoo} 
} 
object run extends Application { 
    /* 
    // this one runs well 
    val a = new Actor { 
     def act() { 
      receive { case 1 => println("1") } 
     } 
    } 
    */ 
    val a = new Actoo { 
     receive { case 1 => println("1") } 
    } 
    a.start 
    a ! 1 
} 

그런 다음 예외 추적은 다음과 같습니다

:

java.lang.AssertionError: assertion failed: receive from channel belonging to other actor 
    at scala.Predef$.assert(Predef.scala:92) 
    at scala.actors.Actor$class.receive(Actor.scala:424) 
    at Actoo.receive(actoo.scala:3) 
    at run$$anon$1.<init>(actoo.scala:16) 
    at run$.<init>(actoo.scala:15) 
    at run$.<clinit>(actoo.scala) 
    at run.main(actoo.scala) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at scala.tools.nsc.ObjectRunner$$anonfun$run$1.apply(ObjectRunner.scala:75) 
    at scala.tools.nsc.ObjectRunner$.withContextClassLoader(ObjectRunner.scala:49) 
    at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:74) 
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:154) 
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala) 

같은 일을 할 수있는 많은 대안이있을 수 있습니다, 위의 코드가 작동하지 않는 이유를 아는 것이 좋습니다.

답변

8

꽤 쉽습니다. 사실이 액터 라이브러리 때문이 아닙니다. 코드

val a = new Actoo { 
     receive { case 1 => println("1") } 
    } 

의 조각은 다음과 같이 컴파일러에 의해 해석됩니다 초기화 몸 receive {...}에 "Actoo의 새 인스턴스를 만들"와 val actoo() 동일하게된다. 따라서, 귀하의 코드는 코드를 해결하기 위해

val a = new Actoo() { 
     receive { case 1 => println("1") } 
    } 

에 equivivalent되어, 당신은 당신이 실제로 (네이티브 스레드 배우 현재 기본 스레드에서 사서함에서받을려고

val a = new Actoo ({ 
     receive { case 1 => println("1") } 
    }) 
+0

작동합니다! 대단히 감사합니다! –

1

를 작성해야 게다가).

증인 다음

Welcome to Scala version 2.7.5.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_13). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> import scala.actors.Actor._ 
import scala.actors.Actor._ 

scala> self ! 123 

scala> receive { case x => println(x) } 
123 

를 이제, 당신이 달성하고자하는 라이브러리 이미 (Actor.actor)에 : BTW

val a = actor { 
    receive { case x => println(x) } 
} 
// no need to start a 
a ! 123 

, 그것을 확장 할 수있는 매우 좋은 생각이다 신청. 대신 def main(args: Array[String])을 사용하십시오.

+0

답변 해 주셔서 감사합니다! 응용 프로그램을 확장 할 수있는 무언가가 있습니까? args가 사용되지 않았을 때 그것들이 동등하다고 생각했습니다 ... –

+0

http://scala-blogs.org/2008/07/application-trait-considered-harmful.html 및 http://blogs.sun.com을 참조하십시오./navi/en_US/entry/scala_puzzlers_part_2를 참조하십시오. 그러나 함정을 아는 경우 응용 프로그램 특성을 사용하여 자유롭게 테스트 할 수 있습니다. –

+0

월터 (Walter), 스택 트레이스를 살펴보면 수신은 Actoo 객체가 아니라 자체 호출임을 알 수 있습니다. 그러나 액터가 아직 시작되지 않은 경우 Actoo 생성자에서 호출이 발생합니다. –

5

Actor 싱글 톤에는 actor 메서드가있어서 원하는대로 처리 할 수도 있습니다. 심지어 start을 자동으로 호출합니다.

import scala.actors.Actor 
import Actor._ 

val a = actor { 
    receive { case 1 => println("1") } 
} 

a ! 1