有没有办法在fsx文件之间共享类型?
当使用#load从多个FSX文件加载包含类型的同一文件时,它们似乎每次都被添加到不同的FS_00xx命名空间中,这意味着您无法传递它们。
有没有办法绕过这种行为而不需要编译成程序集?
答案 0 :(得分:9)
至于
http://msdn.microsoft.com/en-us/library/dd233169.aspx
[。fsx文件]用于在F#中包含非正式测试代码,而无需将测试代码添加到您的应用程序,也无需为其创建单独的项目。默认情况下,即使项目是项目的一部分,脚本文件也不会包含在项目的构建中。
这意味着如果您的项目具有足够的结构以存在此类依赖性问题,则不应使用.fsx
文件,而应使用.fs
文件编写模块/命名空间。也就是说,你真的应该将它们编译成一个程序集。
f#交互式解释器为每个加载的文件生成程序集。如果加载文件两次,则会生成两次字节码,即使它们具有相同的定义和相同的名称,类型也会不同。这意味着您无法在两个.fsx文件之间共享类型,除非其中一个包含其他。
当您#load
文件的类型与您环境中已存在的文件类型相同时,f#交互式解释器可以使用两种不同的策略:
FS_00xx
名称空间中(这样它们实际上与您已加载的名称不同),最终open
生成的名称空间,以便可以从交互式会话中获得名称。由于 fsx文件应该用作非正式测试,因此使用第二种方法更加用户友好(也有技术原因使用第二种方法,主要依赖于{ {1}} VM类型系统,以及在运行时无法更改现有类型的事实。
答案 1 :(得分:6)
[注意:这是more specific question的更具体的答案,与此重复。]
我不认为有一个很好的解决方案。我在一些项目中使用的一个解决方案(如the F# snippets web site)只有一个顶级fsx
文件,可以加载大量fs
个文件。例如,请参阅app.fsx。
因此,您将common.fs
,intMapper.fs
和stringMapper.fs
从caller.fsx
加载,如下所示:
#load "common.fs"
#load "stringMapper.fs"
#load "intMapper.fs"
open Common
在stringMapper.fs
和intMapper.fs
内,你不加载common.fs
。公共类型之前将由caller.fsx
加载,因此事情将起作用。
唯一的问题是intMapper.fs
现在不是独立的脚本文件 - 如果要在编辑器中获得自动完成功能,则需要添加一个fsproj
文件来指定文件顺序。在F#snippets项目中,有a project file,它指定编辑器应该查看和加载文件的顺序。
答案 2 :(得分:1)
在您实际运行的文件中使用fsi.exe(以下示例中的C)中的所有#load
和#open
指令,并确保加载的文件本身不是#load
他们自己的依赖:
文件A.fsx,B.fsx,C.fsx。 B取决于A. C取决于B和A.
B包含
//adding the code below would cause the types defined in A to be loaded twice
//#load "A.fsx"
//#open A
C包含
#load "A.fsx"
#open A
#load "B.fsx"
#open B
不幸的是,这使得所有文件都很难从Visual Studio编辑 - 编辑器不知道它们的依赖关系并显示各种错误。
因此,这有点像黑客,推荐的方法似乎是拥有一个.fsx文件并将其他所有文件编译成.dll:
// file1.fsx #r "MyAssembly.dll"