gpt4 book ai didi

scala - 在 akka/scala 中访问 actor 之外的不可变成员

转载 作者:行者123 更新时间:2023-12-01 03:45:09 27 4
gpt4 key购买 nike

我刚开始学习 Akka/Scala,我写了一个小型聊天服务器。

想象一下这是一个基于房间的聊天服务器,每个人都可以创建自己的房间,并且可以同时在多个房间中。每当房间的成员用完时,房间就会关闭。房间由 id: Int 标识,并且有一个不可变的 name: String .我编写了以下代码来呈现房间。

class Room(val id: Int, val name: String, var host: ActorRef) extends Actor {
def receive = {
case GetId() =>
sender ! id
case GetName() =>
sender ! name
case AddMember(member) => ...
case RemoveMember(member) => ...
case BroadcastMessage(from, message) => ...
}

现在,客户端需要所有房间的 id 和名称来决定加入哪个房间。

val rooms: List[ActorRef] // Obtained somewhere
val getIdFutures: List[Future[Int]] = rooms.map { (_ ? GetId()).mapTo[Int] }
val getNameFutures: List[Future[String]] = rooms.map { (_ ? GetName()).mapTo[String] }
val getIds: Future[List[Int]] = Future.sequence(getIdFutures)
val getNames: Future[List[String]] = Future.sequence(getNameFutures)
for (ids <- getIds; names <- getNames) yield {
ids zip names map { pair =>
val id = pair._1
val name = pair._2
println(s"$id: $name")
}
}

嗯,好的,它有效...但是...有什么方法可以让我访问这些 不可变 成员在 Actor 内更方便?我试图为房间 Actor 制作一个包装器,如下面的代码:

case class RoomWrapper(val id: Int, val name: String, actor: ActorRef)

看起来不错,但是有个问题:现在我要通过 RoomWrapper到处都是对象。房间被破坏时如何得到通知?我不能 context.watch RoomWrapper !

如何解决这个问题?我有没有可能写成这样?

val rooms: List[ActorRef]
rooms map { room =>
println(room.id)
println(room.name)
}

最佳答案

嗯,这只是我的意见。我不认为你应该按照你的建议去做,因为这会使你的代码“多样化”(我的意思是,从 Actor 模型中分离出更具体的东西)。从技术上讲,actor 永远不应该共享任何状态,而且,他们应该只对事件(消息)使用react。在任何情况下,使用 for comprehensions 您可以将上述内容重写为:

for {
room <- rooms
id <- (room ? GetId).mapTo[Int]
name <- (room ? GetName).mapTo[String]
} {
println(id)
println(name)
}

此外,您可以制作一条消息,将 id 和 name 作为元组返回,依此类推。可能性是无限的,但我不允许以这种方式直接访问甚至不可变状态,因为它使我对我正在编码的内容进入应用程序的特定模式的看法有点困惑。

关于scala - 在 akka/scala 中访问 actor 之外的不可变成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27588032/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com