【问题标题】:How to define a ref struct in F# in .NET Standard 2.0?如何在 .NET Standard 2.0 的 F# 中定义 ref 结构?
【发布时间】:2018-12-26 20:05:17
【问题描述】:

F# 4.5 was announced的时候是这样说的:

F# 功能集包括

  • [...]

  • 生成 IsByRefLike 结构的能力(此类结构的示例:Span 和 ReadOnlySpan)。

如何“生产”这些类型?我尝试了 [<IsByRefLike>] 属性,但在 .NET Standard 2.0 中找不到。

【问题讨论】:

    标签: f# ref-struct


    【解决方案1】:

    属性在System.Runtime.CompilerServices中找到

    open System.Runtime.CompilerServices
    
    [<Struct; IsByRefLike>]
    type Apa =
        { A: Span<int>
          B: int }
    

    Phillip Carter 在What's new in F# 4.5 中谈到了这个问题(大约 21 分钟)。

    它适用于 .NET Core 和 .NET Framework,但不适用于 .NET Standard 2.0。

    【讨论】:

    • 感谢您的回答!我已经尝试过了,但不幸的是,.NET Core 中不存在此属性。我将更改问题的措辞。
    • 确实,它在 .NET Standard 2.0 中不可用,仅在 .NET Core 和 .NET Framework 中可用。不过,它已宣布包含在 .NET Standard 2.1 中。
    【解决方案2】:

    从 .NET SDK 6.0.200(在 Visual Studio 2022 17.1 中可用)开始,F# 编译器可识别用户定义的 IsByRefLikeAttributes。以下代码将透明地启用在 .NET Standard 2.0 以及更高版本的框架上定义 ref 结构:

    #if NETSTANDARD2_0
    namespace System.Runtime.CompilerServices
    
    open System
    
    [<Sealed; AttributeUsage(AttributeTargets.Struct)>]
    type IsByrefLikeAttribute() = inherit Attribute()
    #endif
    
    namespace MyLibrary
    
    open System
    open System.Runtime.CompilerServices
    
    [<IsByRefLike>]
    type MyRefStruct(span: Span<int>) = struct end
    

    【讨论】:

      【解决方案3】:

      从技术上讲,这不是答案。

      首先,根据规范,IsByRefLike 是供编译器使用的,而不是供开发人员使用的:https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.isbyreflikeattribute?view=netframework-4.7.2

      第二,当我们确实想从编译器中获得某些东西时,了解我们想要从中获得什么是至关重要的。所以一个正确的问题可能是:我需要 ABC,因为我需要做 XYZ,其中ABC 将与IsByRefLike 相关,然后XYZ 将基于IsByRefLike。这个问题没有解释为什么需要IsByRefLike

      我认为在考虑使用/不使用哪些语言功能时,应始终考虑采用极简主义方法:我们真的需要某种特定的语言功能来完成我们需要的事情吗?想到 F# Option.bind:如果函数是单行函数,那么 Option.bind 很棒。但是,如果有一些如何解析结果的树,那么最好在不使用Option.bind 的情况下明确地执行此操作。

      所以问题是:

      1. 你真的需要IsByRefLike吗?
      2. 如果您认为您需要,请您发布一个您实际确实需要它的示例。

      【讨论】:

      • 1.不,我的代码可以没有它。有问题的数据结构没有保存另一个 ref 结构。 2. 出于安全和正确的原因,我曾考虑使用它来强制类型保留在堆栈中。
      • @TheodoreTsirpanis 我认为数据所在的位置应该是开发人员最不关心的问题,除非由于某种原因明确需要它。我已经给了 F# 任务来对数百万个元素的列表进行排序,它做得很好。所以,我建议你忘记这个属性,除非/直到你真的需要它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-21
      • 1970-01-01
      相关资源
      最近更新 更多