具有静态成员的 F# 接口

Ale*_* 75 5 f# interface

如何在接口中定义静态成员?
为什么不可能呢?

我想强制 F# 类型(类)使用静态方法从字符串(JSON 解析)创建其自身的实例。我想要这个界面示例:

[<Interface>]
type public ILikeJson<'T> =
    abstract member ToJson: unit -> string         // OK
    static abstract member FromJson: string -> 'T  // <-- "static" is not valid here !
Run Code Online (Sandbox Code Playgroud)

或者,字符串的构造函数可以完成这项工作,但静态方法听起来更好,因为它将有一个适当的名称,而且我也不知道如何在接口中定义构造函数。

Ast*_*sti 5

当前的 CLR 规范规定接口仅针对对象实例实现,不适用于类型本身。

C# 8 建议定义静态接口成员,但需要在接口定义本身内提供静态方法的实现。所以你将无法为FromJson每个类实现一个方法。

如果您在 F# 中尝试此操作,您将得到:

FS0868:接口不能包含具体成员的定义。您可能需要在您的类型上定义一个构造函数来指示该类型是一个类。

此问题的一种解决方案是使用静态类型约束。它们允许您查找类型上是否存在方法。

let inline create< ^T when ^T : (static member FromJson: string -> ^T)> json = 
     (^T : (static member FromJson: string -> ^T) (json))
Run Code Online (Sandbox Code Playgroud)

FromJson这支持任何具有带签名的静态方法的类型string -> T

type Number(num: double) =
    member _.Value = num
    static member FromJson (json) = new Number(Double.Parse(json))
Run Code Online (Sandbox Code Playgroud)

并使用:

create<Number> "1.5" //creates a Number(1.5)
Run Code Online (Sandbox Code Playgroud)