2011-12-30 14 views
20

इन दो तत्वों पर विचार करें:एक अक्का में स्काला में विशेषता व्यवहार लिखना प्राप्त विधि

trait Poked extends Actor { 
    override def receive = { 
    case Poke(port, x) => ReceivePoke(port, x) 
    } 

    def ReceivePoke(port: String, x: Any) 
} 

trait Peeked extends Actor { 
    override def receive = { 
    case Peek(port) => ReceivePeek(port) 
    } 

    def ReceivePeek(port: String) 
} 

अब विचार करें मैं एक नया अभिनेता है कि दोनों लक्षण लागू करता है बना सकते हैं:

val peekedpoked = actorRef(new Actor extends Poked with Peeked) 

मैं कैसे लिखूं हैंडलर प्राप्त करें? जैसे कि, रिसीवर, निम्नलिखित कोड की तरह कुछ किया जाना चाहिए, हालांकि "स्वचालित रूप से उत्पन्न" (यानी, सभी लक्षण रचना होना चाहिए):

def receive = (Poked.receive: Receive) orElse (Peeked.receive: Receive) orElse ... 

उत्तर

27

आप super[T] उपयोग कर सकते हैं विशेष रूप से सुपर वर्गों/लक्षण के सदस्यों को संदर्भित करने के।

उदाहरण के लिए:

trait IntActor extends Actor { 
    def receive = { 
     case i: Int => println("Int!") 
    } 
} 

trait StringActor extends Actor { 
    def receive = { 
     case s: String => println("String!") 
    } 
} 

class IntOrString extends Actor with IntActor with StringActor { 
    override def receive = super[IntActor].receive orElse super[StringActor].receive 
} 

val a = actorOf[IntOrString].start 
a ! 5 //prints Int! 
a ! "Hello" //prints String! 

संपादित करें:

ह्यूगो टिप्पणी के जवाब में, यहाँ एक समाधान है कि आप मैन्युअल तार करने के लिए उनके साथ प्राप्त करता है बिना mixins लिखने देता है। मूलतः यह एक परिवर्तनशील List[Receive] के साथ एक आधार विशेषता शामिल है, और प्रत्येक मिश्रित में विशेषता जोड़ने के लिए अपने स्वयं के सूची में प्राप्त एक प्रणाली को बुलाती है।

trait ComposableActor extends Actor { 
    private var receives: List[Receive] = List() 
    protected def registerReceive(receive: Receive) { 
    receives = receive :: receives 
    } 

    def receive = receives reduce {_ orElse _} 
} 

trait IntActor extends ComposableActor { 
    registerReceive { 
    case i: Int => println("Int!") 
    } 
} 

trait StringActor extends ComposableActor { 
    registerReceive { 
    case s: String => println("String!") 
    } 
} 

val a = actorOf(new ComposableActor with IntActor with StringActor).start 
a ! 5 //prints Int! 
a ! "test" //prints String! 

को ध्यान में रखना केवल बात यह है कि के आदेश प्राप्त करता है महत्वपूर्ण नहीं होना चाहिए, के बाद से आप आसानी से जो एक श्रृंखला में पहला है भविष्यवाणी करने के लिए सक्षम नहीं होगा, हालांकि आप से है कि समाधान कर सकता है एक सूची के बजाय एक परिवर्तनीय हैशप का उपयोग कर।

+0

कि बहुत दिलचस्प है, आप :-) धन्यवाद लेकिन यह एक प्रकार IntOrString है कि दोनों एक इंट और एक स्ट्रिंग के पूर्व अस्तित्व को मानता है, और कहा कि IntOrString जानता है कि यह रचना चाहिए वे (जो, अगर मैं एक ढांचा बना रहा हूं, तो दूसरा अनदेखा कर सकता है)। इंटैक्टर और स्ट्रिंगएक्टर लक्षण स्वचालित रूप से लिखना संभव नहीं है? –

+3

ऑर्डर मिश्रित लक्षणों के रैखिकरण द्वारा दिया गया है, इसलिए "अनुमानित" ;-) और प्रीपेडिंग मैचों का उपयोग बाद के लक्षणों के ओवरराइडिंग के माध्यम से किया जाता है। पहले वाले, तो मुझे लगता है कि आपका समाधान बहुत अच्छा है! –

+0

अपने स्केला फू के उत्कृष्ट प्रदर्शन! :-) –

5

आप खाली उपयोग कर सकते हैं आधार अभिनेता वर्ग में प्राप्त करें और श्रृंखला उनकी परिभाषा में प्राप्त करता है। अक्का 2.0 एम 2 के लिए नमूना:

import akka.actor.Actor 
import akka.actor.Props 
import akka.event.Logging 
import akka.actor.ActorSystem 

class Logger extends Actor { 
    val log = Logging(context.system, this) 

    override def receive = new Receive { 
    def apply(any: Any) = {} 
    def isDefinedAt(any: Any) = false 
    } 
} 

trait Errors extends Logger { 
    override def receive = super.receive orElse { 
    case "error" => log.info("received error") 
    } 
} 

trait Warns extends Logger { 
    override def receive = super.receive orElse { 
    case "warn" => log.info("received warn") 
    } 
} 

object Main extends App { 
    val system = ActorSystem("mysystem") 
    val actor = system.actorOf(Props(new Logger with Errors with Warns), name = "logger") 
    actor ! "error" 
    actor ! "warn" 
} 
संबंधित मुद्दे