F#:实际上,“字符串"和“字符串"之间有什么区别?和“字符串选项"?

编程入门 行业动态 更新时间:2024-10-28 02:32:39
本文介绍了F#:实际上,“字符串"和“字符串"之间有什么区别?和“字符串选项"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

实际上,字符串"和字符串选项"之间有什么区别?

除了较小的语法问题,我所看到的唯一区别是,您可以将"null"传递给字符串,而字符串选项则期望"none".

解决方案

我不太喜欢我在下面键入的答案,因为我认为读者会把它看作是对合唱团的关注"或有些复杂的废话",但是我决定将其发布,以防它引起富有成果的评论讨论.

首先,了解这一点可能值得注意

let x : string option = Some(null)

是有效值,表示存在(而不是不存在)某个值(有些而不是无),但该值本身为null. (该值的含义取决于上下文.)

如果您正在寻找我认为是正确的"心理模型的东西,它就会变成这样……

所有引用类型都承认'null'值"的整个概念是.Net和CLR的最大和最昂贵的错误之一.如果今天从头开始重新设计该平台,我想大多数人都同意默认情况下引用将是不可为空的,并且您需要一种明确的机制来选择将其设为null.按照目前的情况,有数百种(如果不是数千种)采用的API,例如字符串foo",并且不希望为null(例如,如果您传递了null,则将抛出ArgumentNullException).显然,这是类型系统可以更好地处理的.理想情况下,``字符串''将表示``非空'',对于 do 想要为null的API的少数,您可以将其拼写出来,例如"Nullable< string> foo"或"Option< string> foo"或其他.因此,这就是现有的.Net平台.

许多功能性语言(例如ML,它是F#的主要影响之一)一生都知道这一点,因此将其类型系统设计为正确",如果要接受空"值,则可以使用泛型类型构造函数,以明确表示可能故意将值的出现"作为合法值的数据.在ML中,这是通过't option"类型完成的-"option"是解决此问题的通用方法. 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

但是,在C#程序集中定义的同一类型将允许null作为F#中的适当值. (并且F#仍然允许后门:

let mc : MyClass = Unchecked.defaultof<_> // mc is null

有效地避开普通的F#类型系统并直接访问CLR.)

这一切听起来似乎很复杂,但是基本上,F#系统使您可以使用"ML"样式的很多F#程序,而不必担心null/NullReferenceExceptions,因为类型系统会阻止您执行此操作这是错误的事情.但是F#必须与.Net很好地集成,因此源自非F#代码的所有类型(如字符串")仍然允许使用空值,因此在使用这些类型进行编程时,您仍然必须像通常那样防御性地进行编程. CLR.关于空值,F#有效地提供了一个避风港,可以轻松地进行无空编程,这是上帝的意图",但同时又可以与.Net的其余部分进行互操作.

我还没有真正回答您的问题,但是如果您遵循我的逻辑,那么您就不会问这个问题(或者会打扰您,这是来自Godel,Escher和Bach的la Joshu的MU).

In real terms, what is the difference between a "string" and a "string option"?

Aside from minor sytnax issues, the only difference I have seen is that you can pass a "null" to string while a string option expects a "none".

解决方案

I don't particularly like the answer I've typed up below, because I think the reader will either see it as 'preaching to the choir' or as 'some complex nonsense', but I've decided to post it anyway, in case it invites fruitful comment-discussion.

First off, it may be noteworthy to understand that

let x : string option = Some(null)

is a valid value, that indicates the presence (rather than absence) of a value (Some rather than None), but the value itself is null. (The meaning of such a value would depend on context.)

If you're looking for what I see as the 'right' mental model, it goes something like this...

The whole notion that "all reference types admit a 'null' value" is one of the biggest and most costly mistakes of .Net and the CLR. If the platform were resdesigned from scratch today, I think most folks agree that references would be non-nullable by default, and you would need an explicit mechanism to opt-in to null. As it stands today, there are hundreds, if not thousands of APIs that take e.g. "string foo" and do not want a null (e.g. would throw ArgumentNullException if you passed null). Clearly this is something better handled by a type system. Ideally, 'string' would mean 'non-null', and for the minority of APIs that do want null, you spell that out, e.g. "Nullable<string> foo" or "Option<string> foo" or whatever. So it's the existing .Net platform that's the 'oddball' here.

Many functional languages (such as ML, one of the main influences of F#) have known this forever, and so designed their type systems 'right', where if you want to admit a 'null' value, you use a generic type constructor to explicitly signal data that intentionally can have 'asbence of a value' as a legal value. In ML, this is done with the "'t option" type - 'option' is a fine, general-purpose solution to this issue. F#'s core is compatible (cross-compiles) with OCaml, an ML dialect, and thus F# inherits this type from its ML ancestry.

But F# also needs to integrate with the CLR, and in the CLR, all references can be null. F# attempts to walk a somewhat fine line, in that you can define new class types in F#, and for those types, F# will behave ML-like (and not easily admit null as a value):

type MyClass() = class end let mc : MyClass = null // does not compile

however the same type defined in a C# assembly will admit null as a proper value in F#. (And F# still allows a back-door:

let mc : MyClass = Unchecked.defaultof<_> // mc is null

to effectively get around the normal F# type system and access the CLR directly.)

This is all starting to sound complicated, but basically the F# system lets you pretty much program lots of F# in the 'ML' style, where you never need to worry about null/NullReferenceExceptions, because the type system prevents you from doing the wrong things here. But F# has to integrate nicely with .Net, so all types that originate from non-F# code (like 'string') still admit null values, and so when programming with those types you still have to program as defensively as you normally do on the CLR. With regards to null, effectively F# provides a haven where it is easy to do 'programming without null, the way God intended', but at the same time interoperate with the rest of .Net.

I haven't really answered your question, but if you follow my logic, then you would not ask the question (or would unask it, a la Joshu's MU from "Godel, Escher, Bach").

更多推荐

F#:实际上,“字符串"和“字符串"之间有什么区别?和“字符串选项"?

本文发布于:2023-11-25 22:20:14,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1631582.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字符串   有什么区别   选项   quot

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!