gpt4 book ai didi

f# - 如何避免对 Actor 实例的可变引用

转载 作者:行者123 更新时间:2023-12-01 11:27:52 25 4
gpt4 key购买 nike

我正尝试在 F# 中获得一些使用 Akka.NET actors 的经验。我有一个场景,当一个 Actor 需要将另一个 Actor 作为他的 child 时。第一个 Actor 将转换每条消息,然后将结果发送给另一个 Actor 。我使用 actorOf2 函数生成 Actor 。这是我的代码:

let actor1 work1 work2 =
let mutable actor2Ref = null
let imp (mailbox : Actor<'a>) msg =
let result = work1 msg
if actor2Ref = null then
actor2Ref <- spawn mailbox.Context "decide-actor" (actorOf2 <| work2)
actor2Ref <! result
imp

let actor1Ref = actor1 work1' work2'
|> actorOf2
|> spawn system "my-actor"

我不喜欢的是可变的 Actor 引用。但是我必须让它可变,因为我需要 mailbox.Context 来生成一个子 actor,而且在第一次调用之前我没有任何上下文。我看到了this question但我不知道如何将它应用到我的函数中。

在更高级的场景中,我需要一组按键分区的子 actor。在这种情况下,我使用的是 Actor 引用词典。有更好的(更像 F# 的)方法吗?

最佳答案

为了在迭代中保持您的“状态”,您需要使迭代明确。这样,您可以将当前“状态”作为尾调用参数传递。就像您链接的问题一样:

let actor1 work1 work2 (mailbox : Actor<'a>) =
let rec imp actor2 =
actor {
let! msg = mailbox.Receive()
let result = work1 msg

let actor2 =
match actor2 with
| Some a -> a // Already spawned on a previous iteration
| None -> spawn mailbox.Context "decide-actor" (actorOf2 <| work2)

actor2 <! result
return! imp (Some actor2)
}

imp None

现在,您不需要使用 actorOf2actorOf 来生成这个 actor,因为它已经有了正确的签名:

let actor1Ref = 
actor1 work1' work2'
|> spawn system "my-actor"

.
编辑
如果您担心额外的样板文件,没有什么能阻止您将样板文件作为函数打包(毕竟,actorOf2 does something similar ):

let actorOfWithState (f: Actor<'msg> -> 'state -> 'msg -> 'state) (initialState: 'state) mailbox =
let rec imp state =
actor {
let! msg = mailbox.Receive()
let newState = f mailbox state msg
return! imp newState
}

imp initialState

然后:

let actor1 work1 work2 (mailbox : Actor<'a>) actor2 msg =
let result = work1 msg
let actor2 =
match actor2 with
| Some a -> a
| None -> spawn mailbox.Context "decide-actor" (actorOf2 work2)

actor2 <! result
actor2

let actor1Ref =
actor1 work1' work2'
|> actorOfWithState
|> spawn system "my-actor"

关于f# - 如何避免对 Actor 实例的可变引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35852307/

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