如何在 F# 中创建类型为 System.Buffers.SpanAction 的委托以用于 String.Create?

How can I create a delegate in F# of the type System.Buffers.SpanAction for use in String.Create?

这个问题也在 F# Slack 上被问到,但由于更广泛的社区看不到这个问题,而且我还没有解决方案,所以我认为在这里问它是有意义的。

基本上,String.CreateSpan 一起创建一个新字符串并使用委托来填充跨度。这通常比以正常方式更改字符串更快:创建一个 char 数组,调用 AsSpan,然后用结果调用适当的 String 构造函数。

这很好用:

let create value = 
    String.Create(12, value, fun buf v-> 
        for i = 0 to buf.Length do
            buf.[i] <- v)

但是当我尝试使用柯里化函数或尝试使用委托时,我收到类型错误。根据 F#,委托的类型为 SpanAction<'T, 'TArg>,其中 'T 在回调中转换为 Span<'T>,而 'TArg 是可用于防止关闭的任何参数。

我尝试了几种变体,但都归结为这个基本想法:

type SpanDelegate<'T, 'TArg> = delegate of Span<'T> * 'TArg -> unit

let callback = 
    new SpanDelegate<char, char>(fun buf v -> 
      for i = 0 to buf.Length do buf.[i] <- v)

let create (value: char) = 
    String.Create(12, value, callback)   // type error on callback

无论我是否将它与原始 lambda 一起使用,我似乎都无法让它工作。欢迎提出想法:).

您的代码不起作用的原因是您正在创建自定义委托 SpanDelegate,但代码需要预定义的委托 SpanAction

我不太确定我理解你的问题是否正确(所以我可能遗漏了一些东西),但如果你创建了预定义的 SpanAction 委托,那么一切似乎都工作正常:

open System
open System.Buffers

let callback = 
    SpanAction<char, char>(fun buf v -> 
      for i = 0 to buf.Length do buf.[i] <- v)

let create (value: char) = 
    String.Create(12, value, callback)