F#对JSON反序列化得到的字符串属性做模式匹配如何消除不全匹配告警
方案1:添加通配符兜底分支
这是成本最低的方案,由于string属于无限取值集合,编译器永远无法穷举所有可能值,因此补充通配符分支处理非预期输入即可消除报错:
match mapping.Name with | "需求" -> // 处理需求类映射 | "任务" -> // 处理任务类映射 | "缺陷" -> // 处理缺陷类映射 | unknownName -> failwithf $"接收到未定义的映射名称:%s{unknownName}"
你可以根据业务需要调整兜底逻辑,比如返回默认值、打日志而非抛出异常。
方案2:使用完整活动模式封装合法取值
通过F#特有的完整活动模式,将所有合法取值的判断逻辑收拢到一处定义,匹配时只要覆盖所有活动模式返回分支,编译器就不会报不完整匹配错误:
// 定义活动模式,枚举所有合法的Name取值 let (|Requirement|Task|Bug|InvalidName|) (name: string) = match name.ToLowerInvariant() with | "requirement" | "需求" -> Requirement | "task" | "任务" -> Task | "bug" | "缺陷" -> Bug | _ -> InvalidName // 后续匹配写法 match mapping.Name with | Requirement -> // 处理需求类映射 | Task -> // 处理任务类映射 | Bug -> // 处理缺陷类映射 | InvalidName -> // 处理非法输入
后续新增合法取值时只需要修改活动模式定义即可,不用散改所有匹配代码。
方案3:映射为枚举类型
如果取值固定,可定义对应枚举类型,反序列化阶段直接将Name字段转为枚举值,对枚举做模式匹配时只要覆盖所有枚举成员,编译器就不会报错:
// 定义枚举 type WorkItemMappingType = | Requirement = 0 | Task = 1 | Bug = 2 // 转换取值(可以内置到反序列化逻辑中) let mappingType = Enum.Parse<WorkItemMappingType>(mapping.Name, ignoreCase = true) // 匹配枚举 match mappingType with | WorkItemMappingType.Requirement -> // 处理需求 | WorkItemMappingType.Task -> // 处理任务 | WorkItemMappingType.Bug -> // 处理缺陷
注意:枚举转换需要处理非预期值的转换异常,你可以用
Enum.TryParse做安全转换,提前过滤非法输入。
内容的提问来源于stack exchange,提问作者Alexander Zeitler
相关产品推荐
相关产品推荐

