在 Groovy 中重载 BigDecimal 的乘法方法

Overload BigDecimal's multiply method in Groovy

我在 Groovy 中创建了一个 class Matrix,并重载了 multiply() 函数,这样我就可以轻松地编写如下内容:

Matrix m1 = [[1.0, 0.0],[0.0,1.0]]
Matrix m2 = m1 * 2.0
Matrix m3 = m1 * m2
Matrix m4 = m1 * [[5.0],[10.0]]

但是现在,假设我写:

Matrix m5 = 2.0 * m1
Matrix m6 = [[5.0,10.0]] * m1

这两行会产生错误,因为 classes BigDecimalArrayList 不能乘以 Matrix.

有没有办法为这些 class 重载 multiply()? (我知道我可以扩展这两个 classes,但是有没有办法告诉 Groovy 在编译代码时使用扩展的 classes?)

您可以在 BigDecimalArrayList 中重载 multiply() 方法。扩展 classes 不会像你希望的那样工作,因为 Groovy 不会从 BigDecimalList 文字创建你的子classes 的实例。

我的第一个建议是简单地坚持 Matrix 实例是 multiply() 方法的接收者的语法。例如:matrix.multiply(随便)。这是为了避免必须创建一堆重复的 multiply() 实现。前任。 Matrix.multiply(BigInteger)BigInteger.multiply(矩阵).

一个例子

无论如何,这是一个如何将矩阵数学方法添加到 BigDecimalList 的示例:

Matrix m1 = [[1.0, 0.0],[0.0,1.0]]
def m2 = m1 * 2.0
def m3 = m1 * m2

use(MatrixMath) {
    def m4 = 2.0 * m1
    def m5 = [[5.0,10.0]] * m1
}

/*
 * IMPORTANT: This is a dummy Matrix implementation.
 * I was bored to death during this particular
 * math lesson.
 * In other words, the matrix math is all made up!
 */
@groovy.transform.TupleConstructor
class Matrix {
    List<List> matrix

    Matrix multiply(BigDecimal number) {
        matrix*.collect { it * 2 }
    }

    Matrix multiply(Matrix other) {
        (matrix + other.matrix)
            .transpose()
            .flatten()
            .collate(2)
            .collect { it[0] * it[1] }
            .collate(2)
    }
}

class MatrixMath {
    static Matrix multiply(BigDecimal number, Matrix matrix) {
        matrix * number
    }

    static Matrix multiply(List list, Matrix matrix) {
        matrix * (list as Matrix)
    }
}

此示例使用 Groovy 类别。我选择了一个类别来将 multiply() 实现放在一个 class 中。

如果矩阵只是 List<List>,请注意,使用这种方法实际上可以摆脱 Matrix class。相反,您可以将所有 multiply() 实现放入 MatrixMath 类别,并使用 List<List> 作为矩阵。