问题 F# - 类型扩充VS类型扩展


F#的类型扩充和类型扩展之间究竟有什么区别,我们真的需要两者吗?

是否存在一个比另一个好的情况,反之亦然?

我问的是因为我最近在F#上做过讲座,讲师谈到了这两个讲座,然后评论说他无法看到两者都被包含在F#语言中的原因。

更新:

好的,所以 弗拉迪斯拉夫佐罗夫 指向包含使用示例的页面的链接 类型增强 在定义自己的类型时,以及扩展(或扩充?)外部类型。


9485
2018-03-23 01:53


起源

你似乎让我们混淆了:)我正在连接Tomas Petricek的博客,与Jon Skeet和Yin Zhu一起写下了这个 - manning.com/petricek ,这是恕我直言,是有史以来最伟大,最详细的F#书籍之一。 - Vladislav Zorov
哎呀,你是对的,我修好了。 :-) - phaz


答案:


以下位来自 MSDN的Type Extensions页面 是相关的(强调我的):

有两种形式的类型扩展略有不同   语法和行为。一个 内在延伸 是一个扩展   出现在同一个命名空间或模块中,在同一个源文件中,和   在类型组件(DLL或可执行文件)中   延长。一个 可选扩展 是一个出现在外面的扩展   类型的原始模块,命名空间或程序集   延长。 当类型为时,内部扩展出现在类型上   通过反射检查,但可选扩展没有。可选的   扩展必须在模块中,并且它们仅在范围内   包含扩展名的模块已打开。

可选扩展的目的很明确。它可以帮助您为不属于程序集的类型注入新功能。例如,FSharpx使用它来创建 各种帮手 用于解析基元类型:

open System

type Boolean with
    static member parse x =
        match bool.TryParse(x) with
        | true,v -> Some v
        | _ -> None

为什么你需要内在的延伸呢?答案是它的便利性。我发现将类型定义细分为多个部分非常有用。

在许多F#库中,我看到了使用以下模式: 类型定义 - >实用程序函数 - >内部扩展。通过这种方式,您可以在类型上定义复杂的实用程序函数,使它们在模块中可用,并且仍可以直接在成员定义中使用它们。你可以看看 复杂类型 在F#PowerPack中查看模式。

编辑:

说实话,我经常使用 类型扩展 和 类型增强 互换。重要的是它们是内在的还是可选的。


9
2018-03-23 07:20





它们是不同的东西。类型扩充,当在同一名称空间,模块和源文件中定义时,实际上在编译时成为该类型的一部分。类型扩展(对于模块和源文件之外的类型的类型扩充)是使用.NET扩展方法实现的。

它们都使用相同的语法,唯一的区别是您提到的类型是否在同一名称空间和程序集中,即您正在扩充自己的代码,并且可以在编译之前将其他方法添加到您的类型中。

资源: http://tomasp.net/blog/fsharp-iii-oop.aspx

编辑:

这是一个术语混淆,他们都指的是同一件事 - 内在的扩展 是 类型扩充 第一种(即相同的命名空间和程序集), 可选扩展 是 类型扩充 第二种类型(即第三方集会,在博客文章中这是 List<T> 增强例子)。

我假设你的讲师正在谈论 类型扩充,他指的是内在的扩展,即第一种类型的扩充,以及他在谈论的时候 类型扩展,他在谈论可选扩展,或第二类扩充。


4
2018-03-23 02:05