F#如何定义接收含字段a的任意匿名记录的函数
实现方案
F# 原生匿名记录没有 Standard ML 那种开放行多态的简写语法,你尝试的{|a: string; _|}/{|a: string; ...|}写法目前不受支持,F# 默认的匿名记录类型是封闭的,标注{|a: string|}只能匹配刚好仅包含a字段的匿名记录。
你可以用**静态解析的类型参数(SRTP)**实现完全等价的能力,编译期校验参数必须存在a: string字段,同时允许携带任意其他字段:
let inline f r = // 约束入参必须包含 string 类型的 a 成员 (^T : (member a : string) r) |> sprintf "Hello %s"
调用示例
// 仅带 a 字段,正常调用 f {| a = "World" |} // 返回 "Hello World" // 携带任意额外字段,同样正常调用 f {| a = "F#"; age = 20; isDebug = true |} // 返回 "Hello F#" // 缺少 a 字段会直接触发编译错误,符合类型安全要求 // f {| b = "test" |} // 编译报错:类型不包含成员“a”
该实现没有运行时开销,和SML原生写法的行为完全一致。如果不需要编译期校验,也可以用动态查找实现,但不推荐,会丢失类型安全保障。
内容的提问来源于stack exchange,提问作者P Varga
相关产品推荐
相关产品推荐

