2011-12-30 27 views
20

Hãy xem xét hai đặc điểm sau đây:Soạn hành vi đặc điểm trong Scala trong một Akka nhận phương pháp

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

Bây giờ xem xét tôi có thể tạo ra một diễn viên mới mà thực hiện cả hai đặc điểm:

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

Làm thế nào để soạn nhận xử lý? ví dụ, người nhận nên một cái gì đó giống như đoạn mã sau, mặc dù "tự động tạo ra" (tức là tất cả những đặc điểm cần soạn):

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

Trả lời

27

Bạn có thể sử dụng để tham khảo super[T] thành viên đặc biệt siêu lớp/đặc điểm.

Ví dụ:

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! 

Edit:

Đáp lại bình luận Hugo, đây là một giải pháp cho phép bạn soạn mixins mà không phải cài dây của họ nhận được với nhau. Về cơ bản nó liên quan đến một đặc điểm cơ bản với một biến thể List[Receive], và mỗi đặc điểm hỗn hợp gọi một phương thức để thêm nhận riêng của nó vào danh sách.

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! 

Điều duy nhất cần lưu ý là thứ tự của các nhận không nên quan trọng, vì bạn sẽ không thể dễ dàng dự đoán cái nào là đầu tiên trong chuỗi, mặc dù bạn có thể giải quyết bằng cách bằng cách sử dụng một hashmap có thể thay đổi thay vì một danh sách.

+0

Đó là rất thú vị, cảm ơn bạn :-) Nhưng nó giả định trước sự tồn tại của một loại IntOrString đó là cả một Int và một String, và rằng IntOrString biết điều đó nên soạn những người (trong đó, nếu tôi đang xây dựng một khuôn khổ, người kia có thể bỏ qua). Không phải là có thể làm cho các đặc điểm của IntActor và StringActor tự động soạn thảo? –

+3

Trình tự được đưa ra bằng cách tuyến tính hóa các đặc tính hỗn hợp, do đó có thể dự đoán được ;-) Và việc sử dụng tính năng chuẩn bị khớp với giá trị ghi đè các đặc điểm sau đó là wrt. trước đó, vì vậy tôi nghĩ rằng giải pháp của bạn là rất tốt đẹp! –

+0

Hiển thị tuyệt vời của scala-fu của bạn! :-) –

5

Bạn có thể sử dụng Lớp nhận tác nhân cơ bản trống và chuỗi nhận được trong định nghĩa của chúng. mẫu cho Akka 2.0-M2:

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" 
} 
Các vấn đề liên quan