【问题标题】:Is it possible to add DivideByInt to existing types? [duplicate]是否可以将 DivideByInt 添加到现有类型? [复制]
【发布时间】:2015-06-02 23:50:44
【问题描述】:

给定TimeSpan 值的列表,我想得到TimeSpan 的平均值。如果我可以这样写就很优雅了:

let durations = [TimeSpan.FromSeconds 4.; TimeSpan.FromSeconds 2.]
let avg = durations |> List.average

但是,编译器抱怨这个:

“TimeSpan”类型不支持“DivideByInt”运算符

这很合理,因为TimeSpan 确实没有定义DivideByInt

为了解决这个问题,我尝试像这样扩展TimeSpan(在使用List.average之前):

type TimeSpan with
    static member DivideByInt (ts : TimeSpan) (i : int) = 
        (float ts.Ticks) / (float i) |> int64 |> TimeSpan.FromTicks

虽然直接使用此实现似乎可以正常工作,但不幸的是,使用List.average 时编译器似乎并不满意。

虽然我非常清楚我可以使用 List.averageBy,或者只是编写一个自定义函数来计算 TimeSpan 值列表的平均值,但我认为如果可以编写 @987654334 会很优雅@。

有没有办法启用该语法?

【问题讨论】:

标签: f#


【解决方案1】:

不,这是不可能的。请参阅此old question。从理论上讲,它可能会在未来的 F# 版本中实现。

【讨论】:

    【解决方案2】:

    当我尝试使用

    重载操作时
    type TimeSpan with
    member this.op_DivideByInt (ts : TimeSpan) (i : int) = 
        (float ts.Ticks) / (float i) |> int64 |> TimeSpan.FromTicks
    
    let durations = [TimeSpan.FromSeconds 4.; TimeSpan.FromSeconds 2.]
    let avg = durations |> List.average
    

    我收到以下编译器警告: Extension members cannot provide operator overloads. Consider defining the operator as part of the type definition instead.

    所以看起来我们不能这样做。

    【讨论】:

    • 根据 MSDN,成员必须是静态的:msdn.microsoft.com/en-us/library/…
    • true,但是在我尝试将其作为实例成员之前,编译器并未将我的代码解释为运算符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多