gpt4 book ai didi

f# - 静态方法的类型约束

转载 作者:行者123 更新时间:2023-12-01 06:24:58 25 4
gpt4 key购买 nike

我正在使用 OpenTK 及其数学库,但不幸的是向量类没有通用接口(interface)。例如 Vector2 ,3 和 4 都有相同的静态方法 SizeInBytes http://www.opentk.com/files/doc/struct_open_t_k_1_1_vector3.html#ae7cbee02af524095ee72226d842c6892

现在我可以重载大量不同的构造函数,但我认为应该可以通过类型约束来解决这个问题。

我正在阅读 http://msdn.microsoft.com/en-us/library/dd233203.aspx我发现了这个

type Class4<'T when 'T : (static member staticMethod1 : unit -> 'T) > =
class end

现在我已经自己尝试过了,但我无法正确使用语法。
type Foo<'T when 'T: (static member SizeInBytes: unit -> int)>(data: 'T []) =
member this.GetBytes() = 'T.SizeInBytes()

let f = Foo([|new Vector3(1.0f,1.0f,1.0f)|])
f.GetBytes()

你能发现问题吗?

编辑:
VS2012 提示这条线 'T.SizeInBytes() //Unexpected symbol or expressionT.SizeInBytes()也不行。

编辑2:

我做了一个不涉及外部库的例子
type Bar() = 
static member Print() = printf "Hello Foo"

type Foo<'T when 'T: (static member Print: unit -> unit)>(data: 'T []) =
member this.Print() = 'T.Print()

let b1 = Bar()
let f = Foo([|b1|])
f.Print()

最佳答案

调用由成员约束保证的事物的正确语法有点晦涩:

type Foo< ^T when ^T: (static member SizeInBytes: unit -> int)>(data: ^T []) =
member inline this.GetBytes() =
(^T : (static member SizeInBytes : unit -> int) ())

请注意 'T必须更改为“静态解析类型变量” ^T - 参见 F# spec 中的词汇表.

您不能调用普通类型变量上的约束指定的成员,因为 .NET 框架不支持,因此 F# 必须将它们编译掉。如果我们尝试使用 'T,则会出现语法错误。在 GetBytes反而。

我认为 MSDN 文档通过 'T 举例说明有点误导。 ,因为尽管您可以编写它们给出的类型,但您永远不能使用约束。

如果您查看 Class4 的 IL 代码示例,约束实际上已经消失:
.class nested public auto ansi serializable Class4`1<T>
extends [mscorlib]System.Object

这是有道理的,因为必须为 .NET 删除成员约束。 type Foo 也是如此。与 ^T类型变量。

另请注意,与所有 inline 相同。 F# 函数,只能从 F# 代码中静态调用,以便编译器可以在调用处内联定义。

如果您尝试从 C# 代码或通过反射调用它,它将引发异常。如果您尝试,您的代码将在运行时失败。

通常,使用 .NET 不支持的 F# 约束是一件棘手的事情,所以如果可能的话,我会尽量避开。

已编辑:鉴于 (a) 我的进一步实验 (b) Gene Belitski 的回答和 (c) idjarn 的评论 inline函数总是被编译为引发异常的 IL。

关于f# - 静态方法的类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20926533/

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