gpt4 book ai didi

Scala:避免可变实例变量

转载 作者:行者123 更新时间:2023-12-02 04:56:07 25 4
gpt4 key购买 nike

我试图避免类中的可变实例变量,但我无法弄清楚在以下情况下如何在我的 Play 应用程序中创建用户:

当用户登录时,像 membershipList 这样的用户信息可以改变。当这样的事情改变时,应用程序使用 Play 的 Ok.feed(...) 作为服务器发送事件通知用户(上交所)。

编辑:@drstevens 指出,单播提要必须移出,因为 User 显示为 Case 类。编辑以使 User 不是案例类。

class User(id: Long, firstName: String, lastName: String, 
membershipList: List[Group], @volatile private var signedIn = true) {
private var infoSentOnce = false;
private val unicastFeed: Option[Enumerator[JsValue]] = if(signedIn) Concurrent.unicast[JsValue](onStart, onComplete, onError) else None

private def onStart(channel: Channel[JsValue]) {
if(signedIn) {
if(!infoSentOnce) {
channel.push(json)
channel.end
infoSentOnce = true;
}
} else {
channel.eofAndEnd
}
}

private def onComplete = ....

private def onError(message: String, iteratee: Iteratee[JsValue]) = .....

def json = {
.....
}

def signedOut = signedIn = false

def feed = unicastFeed
}

Controller 中的 Action 将是:

class MyController extends Controller with MyAuth {
def userFeed = Authenticated { request =>
request.user.feed.fold(Ok(request.user.json)) { feed =>
Ok.feed(feed
>& Concurrent.buffer(10)
>& new EventSource()).as("text/event-stream"))
}
}
}

signedIn & infoSentOnce 是我想将其更改为不可变的两个可变变量。 infoSentOnce 可变也可能与我没有正确理解 Play 的枚举器有关。每当用户信息发生变化时,我都会创建一个新的用户对象,但我会从同一用户的先前实例复制单播枚举器。当创建新的用户实例时,Json 将被推送到用户的单播 channel 中一次。

也许在这里将 infoSentOnce 作为 var 是可以的,因为它不能被任何外部交互修改?

最佳答案

由于您的 User 类本身正在处理事件,因此它必须保持状态,这意味着它是可变的。

不可变类在外部力量完成事情时最有用,比如如果 MyController 正在登录用户,并且可以使 user = user.copy(signedOn = true)。如果类本身正在管理状态,那么,您就需要可变性。

您可以通过用 AtomicBoolean 替换您的 bool 变量来在此处作弊以获取所有 val,但这只会将可变性移到一个级别。

关于Scala:避免可变实例变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22176822/

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