为什么这个代码不够通用甚至更好,为什么甚至检查?

时间:2017-05-24 16:14:54

标签: f#

我对ToBar

的定义出错了
type Foo = {foo: string}
type Bar = {bar: string}

[<AbstractClass>]
type AbstractType< ^T> (fn: ^T -> Foo) =

    member inline this.ToFoo (x: ^T) = fn x
    abstract ToBar: string -> Bar

这是错误消息

This code is not sufficiently generic. 
The type variable  ^T could not be generalized 
because it would escape its scope.

除了(即使在阅读了所有其他SO问题之后)我还没有得到这个错误试图告诉我的内容......但ToBar并不令人惊讶即使使用该类型参数也会出错

1 个答案:

答案 0 :(得分:4)

这是因为ToBar不是inline,这是使用静态解析类型约束的必要条件。但似乎你并不真正需要它们,简单的泛型就足够了。所以只需将^T替换为'T,它就可以正常工作:

[<AbstractClass>]
type AbstractType<'T> (fn: 'T -> Foo) =

    member inline this.ToFoo (x: 'T) = fn x
    abstract ToBar: string -> Bar

如果你再考虑一下,它只会有意义:abstract成员不能真正使用SRTC,因为它在运行时调度,并且需要在编译时知道SRTC类型

在相关的说明中,即使你为了保留SRTC而摆脱ToBar,你也会遇到下一个错误:

error FS1113: The value 'ToFoo' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible

这可以通过将类型本身设为私有来修复:

type private AbstractType< ^T> (fn: ^T -> Foo) =
    member inline this.ToFoo (x: ^T) = fn x

这将起作用,因为无法从外部程序集访问该类型,因此不需要公开其SRTC参数。