属性 'Context' 是 F# 中的静态错误
Property 'Context' is static error in F#
我在将 Akka.Net actor 从 C# 重写为 F# 时遇到问题:
public class Listener : ReceiveActor
{
public Listener()
{
Receive<Messages.Shutdown>(s =>
{
Console.WriteLine($"shutdown {s.Duration}");
Context.System.Terminate();
});
}
}
Actor 应该通过终止 Actor 系统来处理关闭消息。我试着像这样重新实现它:
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 表达式中(有趣)?还是因为它在构造函数中(做)?
你可以这样写:
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 已回答的问题。
想通了。问题是:
我使用了错误的语法来访问基 class 的静态成员。正如@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
方法重载歧义。
我在将 Akka.Net actor 从 C# 重写为 F# 时遇到问题:
public class Listener : ReceiveActor
{
public Listener()
{
Receive<Messages.Shutdown>(s =>
{
Console.WriteLine($"shutdown {s.Duration}");
Context.System.Terminate();
});
}
}
Actor 应该通过终止 Actor 系统来处理关闭消息。我试着像这样重新实现它:
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 表达式中(有趣)?还是因为它在构造函数中(做)?
你可以这样写:
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 已回答的问题。
想通了。问题是:
我使用了错误的语法来访问基 class 的静态成员。正如@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
方法重载歧义。