我编写了这段代码,它在VS.NET 2010中编译并完美运行
module ConfigHandler
open System
open System.Xml
open System.Configuration
let GetConnectionString (key : string) =
ConfigurationManager.ConnectionStrings.Item(key).ConnectionString
然而,当我执行控制+ 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
现在控制+ A,Alt + Enter成功,我很好地告诉我
模块ConfigHandler =开始 val GetConnectionString:string - >串 端
但是现在如果我尝试在VS.NET 2010中编译我的代码,我会收到一条错误消息
库或多文件应用程序中的文件必须以命名空间或模块声明开头,例如'namespace SomeNamespace.SubNamespace'或'module SomeNamespace.SomeModule'
我怎么能同时拥有这两个?能否在VS.NET中编译并能够将模块发送到FSI?
答案 0 :(得分:16)
在你的两个代码片段之间存在一个微小但至关重要的区别,这应该归咎于此。
F#有两种方式来声明module
。第一个是"顶级模块",声明如下:
module MyModule
// ... code goes here
声明模块的另一种方式是"本地模块",如下所示:
module MyModule =
// ... code goes here
"顶级"之间的主要区别和#34;本地"声明是本地声明后跟一个=
符号和#34; local"中的代码。模块必须缩进。
您收到第一个代码段的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
中,它们应该按预期工作。
答案 1 :(得分:7)
常见的解决方案是保留第一个示例并创建一个引用该模块的fsx
文件:
#load "ConfigHandler.fs"
您可以加载多个模块并编写用于实验的管道代码。
如果您确实要将ConfigHandler.fs
直接加载到F#Interactive,可以使用INTERACTIVE
符号和compiler directives:
#if INTERACTIVE
#else
module ConfigHandler
#endif
适用于fsi和fsc。