Istnieją dwa rozwiązania, oba z nich korzystać wyraźny rekurencyjnej definicji pętli, główną koncepcję Akka F # aktorów.
Najpierw można zdefiniować zmienne, które powinny być widoczne tylko wewnątrz zakresu aktora, przed definicji pętli (w przykładzie poniżej Zmieniłem i
definicję odwołanie do komórki, ponieważ zmienne Zmienne nie mogą być przechwytywane przez zamknięć):
let actorRef =
spawn system "my-actor" <| fun mailbox ->
let i = ref 1
let rec loop() =
actor {
let! msg = mailbox.Receive()
match msg with
| Some x -> i := !i + x
| None ->()
return! loop()
}
loop()
jednak bardziej poinformowani rozwiązaniem jest, aby utrzymać swój stan niezmienny podczas obsługi wiadomości i zmienić go tylko podczas przechodzenia w następnych połączeń pętli, podobnie jak to:
let actorRef =
spawn system "my-actor" <| fun mailbox ->
let rec loop i =
actor {
let! msg = mailbox.Receive()
match msg with
| Some x -> return! loop (i + x)
| None -> return! loop i
}
loop 1 // invoke first call with initial state
Nie to, co masz szukając, ale dla [agentów F, podejście idiomatyczne polega na użyciu pętli rekursywnej do przenoszenia stanu] (https://msdn.microsoft.com/en-us/library/ee370357.aspx). Jeśli jednak Akka.NET zmusi cię do ścieżki zorientowanej na mutacje, może się okazać, że nie da się tego zrobić "ładnie". Czy możesz wdrożyć aktora dla Akka.NET w inny sposób niż wynikający z 'ReceiveActor'? Coś, co umożliwi ci korzystanie z pętli rekurencyjnej? –
BTW, jeśli istnieje inne rozwiązanie idiomatyczne, jestem po prostu nieświadomy tego i chciałbym też być wykształcony :) –