实际上,"字符串"和"字符串选项"之间有什么区别?
除了轻微的sytnax问题,我看到的唯一区别是你可以将"null"传递给字符串,而字符串选项需要"none".
Bri*_*ian 28
我并不特别喜欢我在下面输入的答案,因为我认为读者要么将其视为"向合唱团讲道",要么将其视为"一些复杂的废话",但我决定将其发布,无论如何,案例它邀请富有成效的评论讨论.
首先,理解这一点可能值得注意
let x : string option = Some(null)
Run Code Online (Sandbox Code Playgroud)
是一个有效值,表示值的存在(而不是缺席)(Some而不是None),但值本身为null.(这种价值的含义取决于具体情况.)
如果你正在寻找我所看到的"正确"的心理模型,那就是这样的......
"所有引用类型都承认'null'值"的整个概念是.Net和CLR最大和最昂贵的错误之一.如果平台今天从头开始重新设计,我想大多数人都同意默认情况下引用是不可为空的,并且你需要一个明确的机制来选择加入null.就目前而言,有数百个,如果不是数千个API,例如"string foo"并且不想要null(例如,如果传递null则会抛出ArgumentNullException).显然,这是类型系统更好地处理的事情.理想的情况下,"字符串"将意味着"非空",并为少数原料药的不希望空,你拼写出来,比如"可空<字符串>富"或"选项<字符串>富"或什么的.所以现有的.Net平台就是这里的'古怪'.
许多函数式语言(例如ML,F#的主要影响之一)已经永远知道这一点,因此设计了它们的类型系统"正确",如果你想要允许'null'值,你可以使用泛型类型构造函数来明确地发出有意识地将"价值的影响"作为合法价值的数据.在ML中,这是通过"'t选项"类型完成的 - "选项"是一个很好的通用解决方案.F#的核心是与ML方言的OCaml兼容(交叉编译),因此F#从其ML祖先继承了这种类型.
但是F#也需要与CLR集成,而在CLR中,所有引用都可以为null.F#尝试走一条细线,因为你可以在F#中定义新的类类型,对于那些类型,F#将表现为类似ML(并且不容易将null作为值):
type MyClass() = class end
let mc : MyClass = null // does not compile
Run Code Online (Sandbox Code Playgroud)
但是,在C#程序集中定义的相同类型将允许null作为F#中的适当值.(而且F#仍允许后门:
let mc : MyClass = Unchecked.defaultof<_> // mc is null
Run Code Online (Sandbox Code Playgroud)
有效地绕过普通的F#类型系统并直接访问CLR.)
这一切都开始听起来很复杂,但基本上F#系统可以让你在'ML'风格中编写大量的F#,你永远不需要担心null/NullReferenceExceptions,因为类型系统会阻止你做错事这里.但是F#必须很好地与.Net集成,所以所有源自非F#代码的类型(比如'string')仍然允许空值,因此当使用这些类型进行编程时,你仍然需要像通常那样进行防御性编程. CLR.关于null,有效的F#提供了一个避风港,可以很容易地进行"无上帝编程,上帝的意图",但同时与.Net的其余部分进行互操作.
我没有真正回答你的问题,但是如果你遵循我的逻辑,那么你就不会问这个问题(或者不会解决它,来自"Godel,Escher,Bach"的Jos Jos的MU).