在我发表 comments https://github.com/fsharp/fslang-suggestions/issues/349#issuecomment-1124206512
为方便读者,此处复制了示例代码:
let spanOfOptString(os: Option<string>) =
match os with Some(s) -> s.AsSpan()
| None -> raise(Exception())
错误FS0412:类型实例化涉及byref类型.这是通用IL规则所不允许的.
因此,F#将一个无返回函数raise
键入为Exception -> 'a
,其中包含一个free 'a
("OCaml方式"),而类型变量恰好绑定到byref类型ReadOnlySpan
,这是非法的.我觉得我是因为我没有犯下的罪行而受到惩罚...
我可以找到一个解决办法
let checkedSpanOfString(os: Option<string>) =
match os with Some(s) -> s.AsSpan()
| None -> raise(Exception()) // 'a = unit
ReadOnlySpan.Empty // both arms: ReadOnlySpan<char>
https://sharplab.io/#gist:32b520574fde97de8d7389ab04f64bc4
但我觉得这有点难看.我认为我们不应该期望all个byref类型可以使用.Empty
个?(我想除了(ReadOnly
)Span
/Memory
之外,我从来没有使用过任何其他byref类型,但那是另一个故事)
While F# core team doesn't seem to be moving towards introducing the bottom type to the language (which is perhaps a sensible engineering decision),
does anybody have a better alternative to make this work?
Update
@chadnt的答案可以内联以获得
let checkedSpanOfString(os: Option<string>) =
let s = match os with Some(s) -> s
| None -> raise(Exception())
s.AsSpan()
https://sharplab.io/#gist:a5eab805c539c45048b4072fa7b096c5
它的IL看起来比我的原始版本简单得多