Hes*_*han 4 f# records nullable properties
我需要为我的F Sharp记录修改和添加新属性.但是它会为之前没有这个新字段的实例提供错误.我把它设为Nullable,但仍然出现同样的错误,请帮我解决这个问题
我认为你的意思是"可选的",如"在实例化记录时我没有提供的字段".但是,遗憾的是,F#记录中没有可选字段(或者幸运的是,取决于您的观点).您指定的所有记录字段必须在实例化时出现.
另见这个密切相关的问题.
您可以考虑这种权衡:
使用记录.每次更新记录时,F#编译器都会尖叫并提醒您使用此记录的所有位置,并且您现在需要提供其他信息.附加信息可以是None您添加的字段,如果它们是选项.最大的优势:您的代码本身不必处理所有可能的"如果field1丢失该怎么办?如果缺少怎么办field2?"的情况.
使用课程.更新类时,F#编译器不会对您放入类中的信息执行任何类型的完整性检查.(您可以将记录视为所有字段都是构造函数参数的类,并且必须提供所有字段).因此,更新类定义不会产生任何开销,但您的代码需要处理所有缺少的值.
我个人更喜欢唱片,因为它迫使我思考添加新领域的含义.
当然有一个中间立场:您可以使用记录,但通过静态成员或类似的东西实例化所有记录:
type Name =
{
First: string
Family: string
}
static member Create(first, family) = { First = first; Family = family}
Run Code Online (Sandbox Code Playgroud)
如果在您的代码中,您总是使用Name.Create实例化记录,那么您当然可以添加一个MiddleName字段而无需任何消费者代码注意.
该选项类型优于F#中无效,原因很简单,即"未初始化变量"不思考的功能性的方式存在.
让我们从构建代表a的记录开始,该记录VacationRequest必须得到老板的批准.
type VacationRequest =
{Name : string
Date : DateTime
Approval : string option}
Run Code Online (Sandbox Code Playgroud)
您的方法的问题是必须在构造时分配所有字段,因此不会编译:
let holiday =
{Name = "Funk"
Date = DateTime(2020,12,31)}
Run Code Online (Sandbox Code Playgroud)
您可以使用辅助函数来解决此问题,该函数隐式设置选项值.
let fillInRequest name date =
{Name = name
Date = date
Approval = None}
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用辅助函数构建记录.
let holiday = fillInRequest "Funk" <| DateTime(2020,12,31)
Run Code Online (Sandbox Code Playgroud)
在向FSI发送代码时注意到了一些有趣的事情.
Run Code Online (Sandbox Code Playgroud)val holiday : VacationRequest = {Name = "Funk"; Date = 31/12/2020 12:00:00 ; Approval = null;}
然后老板可以更新请求(创建新记录)
let approvedHoliday =
{holiday with Approval = Some "boss' name"}
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)val approvedHoliday : VacationRequest = {Name = "Funk"; Date = 31/12/2020 12:00:00 ; Approval = Some "boss' name";}
或者不加改变地发回去
let betterLuckNextTime = holiday
Run Code Online (Sandbox Code Playgroud)