如何在不中断对其他类型的支持的情况下适当地重载全局(+)和(*) [英] How to properly overload global (+) and (*) without breaking support for other types

查看:81
本文介绍了如何在不中断对其他类型的支持的情况下适当地重载全局(+)和(*)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经导入了向量数学库,并希望添加自己的(*)和(+)运算符,同时保留现有的基本int和float运算符.

I have imported a vector math library, and would like to add my own (*) and (+) operators while preserving the existing operators for basic int and float.

我尝试了以下操作:

let inline (*) (x : float) (y : Vector) = y.Multiply(x)
let inline (*) (x : Vector) (y : float) = x.Multiply(y)
let inline (+) (x : Vector) (y : Vector) = x.Add(y)

有两个问题:

  1. 似乎删除了int + intint * int以及
  2. 第二行(旨在实现可交换性)未编译,因为它是重复定义".
  1. It seems to remove int + int and int * int, and
  2. The 2nd line (which is intended to complete commutativity) does not compile because it is a "duplicate definition".

如何在导入的Vector类型上定义一些可交换运算符,同时又不丢失int和float上的这些运算符?

How can I go about defining some commutative operators on my imported Vector type while also not losing these operations on ints and floats?

(我希望能够使用*和+在其他地方编写通用代码,而不必指定float/Vector/int类型约束).

(I want to be able to write generic code elsewhere using * and +, without having to specify float/Vector/int type constraints).

推荐答案

如果您能够修改库的源代码,则通过类型扩展添加一些重载会更简单:

If you are able to modify source code of the library, it's simpler to add a few overloads via type extensions:

type Vector with
    static member (*) (x : Vector) (y : float) = x.Multiply(y)
    static member (+) (x : Vector) (y : Vector) = x.Add(y)

但是,如果第一个操作数具有基本类型(例如您的第一个示例),则重载解析不再起作用.

However, if the first operand has a primitive type (e.g your first example), overloading resolution doesn't work any more.

无论如何,您可以利用成员重载并将约束传播到内联函数:

At any rate, you can exploit member overloading and propagate constraints to an inline function:

type VectorOverloadsMult =
    | VectorOverloadsMult
    static member (?<-) (VectorOverloadsMult, x: float, y: Vector) = y.Multiply(x)
    static member (?<-) (VectorOverloadsMult, x: Vector, y: float) = x.Multiply(y)     
    static member inline (?<-) (VectorOverloadsMult, x, y) = x * y

let inline (*) x y = (?<-) VectorOverloadsMult x y

这适用于使用(*)的现有类型,因为我们将它们保留在最后一个静态成员中.您可以对(+)运算符执行相同的操作.

This works for existing types with (*) since we preserve them in the last static member. You can do the same for (+) operator.

let v: Vector = ... // Declare a Vector value
let a = 2.0 * v
let b = v * 2.0
let c = 2 * 3
let d = 2.0 * 3.0

即使您无法修改Vector类型,该技术也可以使用.

This technique works even when you cannot modify the Vector type.

这篇关于如何在不中断对其他类型的支持的情况下适当地重载全局(+)和(*)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆