如何从record实例中提取所有字段值生成对应类型的数组
解决方案
针对你需要将Record所有字段转换为数组的需求,提供两种常用实现方案:
方案1:通用反射实现(自动适配字段变更)
利用F#内置的Record反射API,可以不用硬编码任何字段名,后续新增/删除Probabilities的字段时不需要修改转换逻辑:
open Microsoft.FSharp.Reflection type Probability = Probability of float type Probabilities = { Pp: Probability; Pf: Probability; Pd: Probability; Pg: Probability; } // 通用Record转字段数组函数,仅适用于所有字段都是Probability类型的Record let toProbabilityArray<'T> (record: 'T) = if not <| FSharpType.IsRecord(typeof<'T>) then invalidArg (nameof record) "输入参数必须为F# Record类型" FSharpValue.GetRecordFields(record) |> Array.map (fun fieldValue -> fieldValue :?> Probability) let calculatingSum (probabilities : Probabilities) = probabilities |> toProbabilityArray |> Array.map (fun (Probability value) -> value) // 解包Probability单例获取float值 |> Array.sum
该方案的唯一缺点是存在极小的反射性能开销,如果你的逻辑需要超高频调用,可以选择方案2。
方案2:静态转换函数(零性能损耗)
仅需要一次性硬编码字段列表,后续所有需要转数组的场景都可以复用该函数,避免重复编写字段取值逻辑:
type Probability = Probability of float type Probabilities = { Pp: Probability; Pf: Probability; Pd: Probability; Pg: Probability; } // 一次性定义转换逻辑,全局复用 let probabilitiesToArray (p: Probabilities) = [| p.Pp; p.Pf; p.Pd; p.Pg |] let calculatingSum (probabilities : Probabilities) = probabilities |> probabilitiesToArray |> Array.map (fun (Probability value) -> value) |> Array.sum
注:你原代码中的参数名
probablities为拼写错误,正确拼写为probabilities
内容的提问来源于stack exchange,提问作者Viktor Jeppesen
相关产品推荐
相关产品推荐

