gpt4 book ai didi

generics - 当组合泛型和非泛型类时,类型变量转义作用域

转载 作者:行者123 更新时间:2023-12-04 13:37:09 25 4
gpt4 key购买 nike

我在F#中有一个带有单个类型参数的泛型类,并且想创建一个包含工厂方法的静态类。当我编写类时,F#编译器会生成与“类型变量转义其范围”有关的错误。我的问题是为什么存在错误以及如何解决该错误。

我创建了一个最小尺寸的片段来演示这个问题:

type Foo<'a>(element : 'a) =

member this.Copy () = Bar.Create(element)

and Bar =

static member Create(element : 'a) = new Foo<'a>(element)

类型之间存在相互递归,因为我希望 Foo<'a>类型能够在静态类中调用工厂方法。上面的代码片段没有编译,错误是:“类型推断导致类型变量a逃避其范围。请考虑添加显式类型参数声明或将代码调整为通用性较低。”该错误被注册为位于 Create类的 Bar方法中。不幸的是,我不太了解这个问题,也不知道如何解决。有任何想法吗?

这是另外一个观察结果。片段
type Foo<'a>(element : 'a) =

member this.Element = element

and Bar =

static member Create(element : 'a) = new Foo<'a>(element)

确实可以编译。因此,该问题似乎与基于 Copy()类的 Foo<'a>方法进行的类型推断有关。此外,摘要
type Foo<'a>(element : 'a) =

member this.Copy () = Bar.Create(element)

and Bar =

static member Create<'a>(element) = new Foo<'a>(element)

是代码的更类似于C#的版本(其中静态方法显式地变为通用的),该版本也无法编译,并出现错误“此代码不够通用。类型变量'a无法通用,因为它将逃脱它的范围。”

最佳答案

递归成员的类型推断通常要求至少在某些定义上进行类型注释。但是,有时您可以通过重新定义定义来避免这种情况,至少在简化的repro中可以这样:

type Bar = 
static member Create(element) = Foo(element)
and Foo<'a>(element:'a) =
member this.Copy() = Bar.Create(element)

(请注意,我什至已经删除了 element中的 Bar.Create上的注释)。

不幸的是,我不知道有一个简单易懂的解释来确切说明在任何特定情况下将需要哪些注释。

关于generics - 当组合泛型和非泛型类时,类型变量转义作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41746333/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com