代码之家  ›  专栏  ›  技术社区  ›  LOST

F 4.5中的Byref返回

  •  9
  • LOST  · 技术社区  · 8 年前

    我正在尝试向具有byref返回方法的类型添加一个f样式的接口。 代码如下:

    type IPool<'P, 'T when 'T: struct> =
      abstract member GetReference: ITypedPointer<'P, 'T> -> byref<'T>
    
    let Ref<'TPool, 'P, 'T when 'TPool :> IPool<'P, 'T>> (pool: 'TPool) pointer =
      pool.GetReference pointer
    

    令我惊讶的是,在我介绍 IPool 接口。在此之前,REF本身包含了一个类似的实现方式。 &pool.data.[idx] ,工作很好。

    我试着每晚安装一次f tools,因为最新版本并不正式支持byref returns,而且介绍它们的pr最近已经完成: https://github.com/Microsoft/visualfsharp/pull/4888

    但是,我还是 error FS3209: The address of the variable 'copyOfStruct' cannot be used at this point. A method or function may not return the address of this local value. 在visual studio中。类型 outref<T> 似乎仍然没有可用的。我遗漏了什么吗?

    我也试着放下 pointer 参数,然后返回 pool.GetReference 只获取不同的错误消息。

    附加:最终目标是能够

    let aref = Ref pool ptr
    let bref = Ref pool ptr
    aref <- 42
    assert(aref = bref)
    

    例如,给调用者一个对内部存储器的直接引用,通常由数组支持,类似于 Span<T> 是的。我之所以这样做是因为性能原因,所以分配给Ref.的每一个电话都是不好的。

    2 回复  |  直到 8 年前
        1
  •  1
  •   LOST    7 年前

    由于某种原因,减少泛化有助于消除错误:

    let Ref<'P, 'T when 'T: struct> (pool: IPool<'P, 'T>) pointer = pool.GetReference pointer
    

    解决方案提供

    https://github.com/Microsoft/visualfsharp/issues/5366#issuecomment-407521220

    尽管它不能解释为什么原始代码不能编译。

        2
  •  0
  •   Aaron M. Eshbach    8 年前

    我不认为标准做法是 byref 键入。这种类型实际上用于方法参数,主要用于 out ref 参数。看一看 this StackOverflow question 为了一个好的解释。

    您可以做的是将接口上的方法更改为 ITypedPointer<'P,'T> byref<'T> (使用 拜里夫 不允许使用CurrId参数)返回 unit 相反。然后你可以打电话 GetReference 像任何标准的.NET方法一样 外面的 c中的参数。看起来像这样:

    type ITypedPointer<'P, 'T> = interface end
    
    type IPool<'P, 'T when 'T: struct> =
      abstract member GetReference: ITypedPointer<'P, 'T> * byref<'T> -> unit
    
    let Ref<'TPool, 'P, 'T when 'TPool :> IPool<'P, 'T>> (pool: 'TPool) pointer =
      let mutable value = Unchecked.defaultof<'T>
      pool.GetReference(pointer, &value)
      value
    
    推荐文章