这是一个愚蠢的问题。我一直在读F#上的几本书,找不到什么可以解释你放的时间;;在发表声明后,我也无法在阅读中找到模式。你什么时候用双分号结束声明?
答案 0 :(得分:34)
在不应与OCaml兼容的非交互式F#代码中,您不需要需要双分号。在OCaml兼容模式下,您可以在顶级功能声明结束时使用它(在最新版本中,您可以使用扩展名为.ml
的文件或添加#light "off"
来切换到此模式到顶部)。
如果您在Visual Studio中使用命令行fsi.exe
工具或F#Interactive,那么您将使用;;
结束F#的当前输入。
当我在StackOverflow(以及来自my book的代码示例)中发布代码示例时,我在列表中使用;;
时,我还想显示评估表达式的结果F#interactive:
列出F#interactive
> "Hello" + " world!";;
val it : string = "Hello world!"
> 1 + 2;;
val it : int = 3
标准F#源代码
let n = 1 + 2
printf "Hello world!"
有时将输出显示为列表的一部分也很有用,所以我觉得这个符号非常有用,但我从来没有在任何地方解释过,所以你问的很好!
答案 1 :(得分:9)
您是在谈论F#正确还是在F#Interactive中运行F#功能?在F#Interactive ;;强制执行刚输入的代码。除此之外 ;;没有任何我知道的特殊含义
答案 2 :(得分:6)
在F#中,唯一需要;;
的地方是以交互模式结束表达式。
;;
从OCaml的转换中遗留下来,而OCaml又从Caml Light中遗留下来。最初;;
用于结束顶级“短语” - 即let
,type
等。由于典型模块包含一个;;
,因此OCaml可选let
一系列;;
语句,最后可能有一个语句来调用main函数。如果您偏离此模式,则需要将语句与;;
分开。不幸的是,在OCaml中,当do
是可选的而非需要时很难学习。
但是,F#引入了对OCaml语法的两个相关修改:缩进和do
。顶级语句必须在do
块内,并且块需要缩进,因此F#始终知道每个顶级语句以;;
开头并且缩进并以outdent结束。不再需要{{1}}。
总的来说,你需要知道的是[O'] Caml的语法很糟糕,而且F#修复了很多问题,但仍然存在很多令人困惑的向后兼容性。 (我相信F#仍然可以编译很多OCaml代码。)
注意:这个答案是基于我对OCaml和the link Adam Gent posted的经验(遗憾的是,除非你知道OCaml,否则不会很有启发性。)
答案 3 :(得分:3)
符号和操作员参考(F#)
http://msdn.microsoft.com/en-us/library/dd233228(v=VS.100).aspx
半冒号:
•分隔表达式(主要用于详细语法)。
•分隔列表的元素。
•分隔记录的字段。
Double Semi Colon:
http://www.ffconsultancy.com/products/fsharp_journal/free/introduction.html
F#.NET Journal中的文章引用F#代码,因为它将出现在交互式会话中。具体地,交互式会话提供>提示,需要双分号;;用于强制评估的代码段末尾的标识符,并返回结果定义和值的名称(如果有)和类型。
答案 4 :(得分:2)
我怀疑您已经看到在默认情况下未启用#light语法时编写的F#代码(默认情况下,对于2009年5月的CTP以及之后的版本和Visual Studio 2010,#light语法已启用)然后{{ 1}}表示函数声明的结束。
那么#light语法是什么?它附带#light声明:
#light声明制作 空白显着。允许 开发者省略某些关键字 例如in,;,;;,begin和end。
这是一个没有#light语法编写的代码:
;;
并使用轻量语法:
let halfWay a b =
let dif = b - a in
let mid = dif / 2 in
mid + a;;
如上所述,您现在可以省略#light声明(如果您使用的是最近的CTP或Visual Studio 2010,则应该如此)。
如果您想了解有关#light语法的更多信息,请参阅此主题:F# - Should I learn with or without #light?
答案 5 :(得分:2)
当您直接在交互式会话中键入时,双分号用于标记可在F#interactive中进行评估的代码块的结尾。例如,将其用作计算器时。
这在F#中很少见,因为您通常将代码写入脚本文件,突出显示它并使用ALT + ENTER对其进行评估,Visual Studio会在最后为您有效地注入;;
。
OCaml是一样的。
文献经常引用编写的代码,如果它已被输入到交互式会话中,因为这是一种清晰的方式,不仅可以传达代码,还可以传达其推断类型。例如:
> [1; 2; 3];;
val it : int list = [1; 2; 3]
这意味着您将表达式[1; 2; 3]
键入交互式会话,然后;;
表示可以交互式评估的代码块结束,编译器回复{{1}描述表达式求值为val it : int list = [1; 2; 3]
类型的值。
答案 6 :(得分:0)
双重冒号没有目的(在F#互动之外)。分号according to MSDN:
- 分隔表达式(主要用于 用详细的语法)。
- 中隔离 列表的元素。
- 中隔离 记录的字段。
因此,在第一个实例中,;;
将第一个分号之前的表达式与第二个分号之前的空表达式分开,并将该空表达式与之后的任何内容分开。第二个分号(就像在C#或C ++中一样)。
在列表的实例中,我怀疑您在定义空列表元素时会出错。
关于记录,我怀疑它与分离表达式类似,有效地忽略了分号之间的空白空间。
F#interactive在看到双分号时执行输入的F#。
[更新以涵盖F#互动 - 由mfeingold提供)
答案 7 :(得分:0)
答案 8 :(得分:0)
当使用分号作为列表中的分隔符而不是逗号时,双分号的历史可以追溯到ML的开头。在50:15左右的这段ICFP 2010 - Tribute to Robin Milner视频中,迈克戈登提到:
在F#上有人谈到有人问“为什么F#命令结束时会有双分号?”原因是原始ML中列表中的分隔符是分号,所以如果你想要一个列表1; 2; 3;并将它放在单独的行 - 如果你用分号结束一行你没有结束短语,所以使用双分号意味着表达式的结束。然后在标准ML中,列表的分隔符变为逗号,这意味着您可以使用单个分号来结束列表。