这有效
open System
let f = Action(fun () -> Unchecked.defaultof<_>)
Run Code Online (Sandbox Code Playgroud)
但是这个
let f = System.Action(fun () -> Unchecked.defaultof<_>)
Run Code Online (Sandbox Code Playgroud)
产生编译错误
存在多种类型,称为"动作",采用不同数量的通用参数.提供一种类型的实例来消除歧义的类型的分辨率,例如, '操作< ,,_, ,,_, ,,_>'.
我知道我可以通过添加一个类型参数占位符(System.Action<_>(...))来修复它,但是知道它们为什么表现不同?
在规范第14.1.9节中找到了这个:
F打开模块或名称空间声明组时,项目将添加到名称环境中,如下所示:
- 将类型添加到TypeNames表.如果该类型有一个CLI-错位通用名称,如
List'1再一个条目下都加List和List'1.
是否为完全限定类型(省略了类型参数)复制了此行为?它似乎不是这样.
我同意 @James 的观点,即这与 Connect 上提交的错误有关,但我认为情况略有不同。无论如何,我认为这不是预期的行为。您可以将其报告给microsoft dot com的fsbugs吗?
无论如何 - 我做了一些调试,这是我到目前为止发现的:
看来编译器使用不同的代码路径来解析 nameAction和 name System.Action。当解析另一个时,它会搜索所有加载的模块(即程序集)以查找名为的类型System.Action(请参阅开源版本的文件ResolveLongIndentAsModuleOrNamespaceThen中的函数)。nameres.fs
Action这找到了(一个 inmscorlib和另一个 in )的两个定义System.Core。我认为问题来自这样一个事实:名称解析只是迭代结果 - 它找到第一个(来自System.Core),它没有可用的重载(因为它的范围从Action<_,_,_,_,_>到 具有大约 15 个类型参数的版本)。找到该类型后,它会报告错误,甚至不查看是否有其他类型(在另一个程序集中)可以使用。
如果您不引用系统程序集,则 F# 编译器可以很好地解决重载问题。在不带参数的情况下运行编译器会引用默认的程序集集,因此这不起作用:
fsc test.fs
Run Code Online (Sandbox Code Playgroud)
但如果我添加该--noframework标志,那么它编译时不会出现问题:
fsc --noframework test.fs
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
557 次 |
| 最近记录: |