F#中结构体记录与结构体DU是否存在其他默认初始化场景?
F#中结构体记录/可区分联合的默认初始化场景
首先回顾背景:
F#中定义带<Struct>特性的可区分联合或记录类型:
// 结构体可区分联合 [<Struct>] type Foo = Foo of string // 结构体记录 [<Struct>] type Bar = { Name : string }
C#中可以直接通过new Foo()或数组隐式初始化这类类型,但F#中直接写let foo = new Foo()会编译失败。不过F#里仍存在几种可以默认初始化这些结构体的场景:
- 数组初始化
和C#逻辑一致,F#中创建结构体类型的数组时,会自动为每个元素分配默认值:
// 创建包含10个默认Foo实例的数组 let foos : Foo[] = Array.zeroCreate 10 // 或者用Array.init指定数量,返回默认值 let bars = Array.init 5 (fun _ -> Unchecked.defaultof<Bar>)
此时数组内的每个元素都是对应结构体的默认内存表示(比如Foo的内部字符串为null,Bar的Name字段为null)。
- 使用
Unchecked.defaultof<_>获取默认实例
通过Unchecked.defaultof<StructType>可以直接获取结构体的默认值,它会绕过F#对显式默认构造的限制:
let defaultFoo = Unchecked.defaultof<Foo> let defaultBar = Unchecked.defaultof<Bar>
注意不要使用普通的defaultof<_>,因为它会检查类型是否允许显式默认构造,而结构体记录/DU在F#中是被禁止的,会触发编译错误。
- 作为可选参数的默认值
可以将默认初始化的结构体实例设为函数可选参数的默认值:
// 使用Option.defaultValue提供默认值 let processBar (bar : Bar option) = let actualBar = bar |> Option.defaultValue (Unchecked.defaultof<Bar>) // 后续处理逻辑 // 直接在参数定义中设置默认值 let processFoo (foo : Foo = Unchecked.defaultof<Foo>) = // 后续处理逻辑
调用函数时如果不传入对应参数,就会使用默认初始化的结构体实例。
- 泛型代码中的
DefaultValue约束
在泛型函数中,通过添加new : unit -> 'T约束,可以创建结构体的默认实例:
let getDefault<'T when 'T : struct and 'T : (new : unit -> 'T)> () = new 'T()
这种场景下,即使是非泛型代码中不能直接new Foo(),泛型约束也允许创建默认实例。
内容的提问来源于stack exchange,提问作者jfMR
相关产品推荐
相关产品推荐

