F#由于单元原因导致接口继承失败
有人知道为什么编译失败吗F#由于单元原因导致接口继承失败,f#,unit-type,F#,Unit Type,有人知道为什么编译失败吗 type MyInterface<'input, 'output> = abstract member MyFun: 'input -> 'output type MyClass() = interface MyInterface<string, unit> with member this.MyFun(input: string) = () //fails with error FS0017:
type MyInterface<'input, 'output> =
abstract member MyFun: 'input -> 'output
type MyClass() =
interface MyInterface<string, unit> with
member this.MyFun(input: string) = ()
//fails with error FS0017: The member 'MyFun : string -> unit' does not have the correct type to override the corresponding abstract method.
type MyUnit = MyUnit
type MyClass2() =
//success
interface MyInterface<string, MyUnit> with
member this.MyFun(input: string) = MyUnit
类型MyInterface=
抽象成员MyFun:“输入->”输出
键入MyClass()=
接口MyInterface与
成员this.MyFun(输入:string)=()
//失败,错误为FS0017:成员“MyFun:string->unit”的类型不正确,无法重写相应的抽象方法。
类型MyUnit=MyUnit
键入MyClass2()
//成功
接口MyInterface与
成员this.MyFun(输入:string)=MyUnit
在F#语言中,这看起来像是一个棘手的问题,但我不确定它是否符合设计限制或编译器中的错误。如果是受设计限制,那么错误消息应该这样说(因为目前,它没有多大意义)
无论如何,问题是F#编译器不会生成实际包含IL中单元
类型的代码。它将其替换为void
(当用作返回类型时)或空参数列表(当用作方法或函数参数时)
这意味着在MyClass
类型中,编译器决定将MyFun
成员编译为一个方法,该方法接受string
并返回void
(但不能将void
用作泛型类型参数,因此这根本不起作用)。原则上,在这种情况下,编译器可以使用实际的单元
类型(因为这是使其工作的唯一方法),但这可能会在其他地方造成其他不一致
我认为,你创建
MyUnit
的技巧是解决这个问题的完美方法。甚至核心F#库在实现的某些地方(在异步工作流中)也使用了类似于MyUnit
的东西来处理unit
(及其编译方式)的一些限制。多亏了Tomas。我在其他地方没有看到过这个问题(例如,在使用let;)的普通函数中)@Stefan:如果使用unit
类型作为参数(函数或类型),那么它通常是好的。这种缺陷/限制可能只出现在实现抽象成员时(这对于F#编译器来说有点棘手,因为继承在.NET中非常复杂),有趣的是,它在C#中工作,我可以在F#中使用函数。可能应该作为bug报告。