我编写了这段代码,它在VS.NET 2010中编译并完美地运行
module ConfigHandler
open System
open System.Xml
open System.Configuration
let GetConnectionString (key : string) =
ConfigurationManager.ConnectionStrings.Item(key).ConnectionString
Run Code Online (Sandbox Code Playgroud)
但是,当我执行控制+ A和Alt + Enter将其发送到FSI时,我收到错误
ConfigHandler.fs(2,1):错误FS0010:定义中结构化构造的意外启动.预期'='或其他令牌.
好.
所以我将我的代码更改为
module ConfigHandler =
open System
open System.Xml
open System.Configuration
let GetConnectionString (key : string) =
ConfigurationManager.ConnectionStrings.Item(key).ConnectionString
Run Code Online (Sandbox Code Playgroud)
现在Control + A,Alt + Enter成功了,我很好地告诉我FSI
module ConfigHandler = begin val GetConnectionString:string - > string end
但是现在如果我尝试在VS.NET 2010中编译我的代码,我会收到一条错误消息
库或多文件应用程序中的文件必须以命名空间或模块声明开头,例如'namespace SomeNamespace.SubNamespace'或'module SomeNamespace.SomeModule'
我怎么能两个都有?能否在VS.NET中编译并能够将模块发送到FSI?
Jac*_* P. 17
在你的两个代码片段之间存在一个微小但至关重要的区别,这应该归咎于此.
F#有两种声明方式module.第一个是"顶级模块",声明如下:
module MyModule
// ... code goes here
Run Code Online (Sandbox Code Playgroud)
声明模块的另一种方式是"本地模块",如下所示:
module MyModule =
// ... code goes here
Run Code Online (Sandbox Code Playgroud)
"顶级"和"本地"声明之间的主要区别在于本地声明后跟一个=符号,"本地"模块中的代码必须缩进.
您收到ConfigHandler.fs(2,1): error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token.第一个代码段的消息的原因是您无法声明顶级模块fsi.
将=符号添加到模块定义后,它会从顶级模块更改为本地模块.从那里,您得到了错误,Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'因为本地模块必须嵌套在顶级模块或命名空间中.fsi不允许您定义命名空间(或顶级模块),因此如果您想将整个文件复制粘贴到fsi唯一的方式,那么如果您使用编译指令作为@pad提到的话.否则,您只需将本地模块定义(不包含包含名称空间)复制粘贴到fsi它们中,它们应该按预期工作.
参考: MSDN上的模块(F#)
常见的解决方案是保留第一个示例并创建一个fsx引用该模块的文件:
#load "ConfigHandler.fs"
Run Code Online (Sandbox Code Playgroud)
您可以加载多个模块并编写用于实验的管道代码.
如果您确实想ConfigHandler.fs直接加载到F#Interactive,可以使用INTERACTIVE符号和编译器指令:
#if INTERACTIVE
#else
module ConfigHandler
#endif
Run Code Online (Sandbox Code Playgroud)
适用于fsi和fsc.