我有一个问题,就是将C#中的Akka.Net演员重写为F#:
public class Listener : ReceiveActor
{
public Listener()
{
Receive<Messages.Shutdown>(s =>
{
Console.WriteLine($"shutdown {s.Duration}");
Context.System.Terminate();
});
}
}
Actor应该通过终止actor系统来处理Shutdown消息。我试图像这样重新实现它:
type Listener() =
inherit ReceiveActor()
do
base.Receive<Messages>(fun m ->
match m with
| Shutdown(duration) ->
printf "shutdown %s" (duration.ToString())
base.Context.System.Terminate()
true
| _ -> false)
但base.Context.System.Terminate()
行Property 'Context' is static
中存在编译错误。这段代码有什么问题?为什么我不能访问基类的静态属性?是因为这段代码是lambda expresion(有趣)吗?或者因为它在构造函数中(do)?
答案 0 :(得分:5)
你可以这样写:
type Listener() =
inherit ReceiveActor()
do
base.Receive<Messages>(fun m ->
match m with
| Shutdown(duration) ->
printf "shutdown %s" (duration.ToString())
ReceiveActor.Context.System.Terminate()
true
| _ -> false)
请注意,您可以使用function
代替match
... with
:
base.Receive<Messages>(function
| Shutdown(duration) ->
然后printfn
相当于WriteLine,而且:
printfn "shutdown %s" (duration.ToString())
与:
相同printfn "shutdown %O" duration
<强>更新强>
如果您的错误消息显示为静态属性,则无法在lambda中使用该属性,对于该问题,请参阅this已回答的问题。
答案 1 :(得分:4)
想出来。问题是:
我使用了错误的语法来访问基类的静态成员。正如@ildjarn所评论的那样,它应该是ReceiveActor.Context
,而不是base.Context
。
无法从lambda表达式访问受保护的成员。处理程序需要是成员方法。
工作版:
type Listener() as this =
inherit ReceiveActor()
do
base.Receive<Messages>(this.handle)
member this.handle(message: Messages): bool =
match message with
| Shutdown(duration) ->
printf "shutdown %s" (duration.ToString())
ReceiveActor.Context.System.Terminate()
true
| _ -> false
重要更改:1。as this
让我们从构造函数调用成员方法,2。编译器需要在handle
方法中键入注释以解决Receive
方法重载歧义。