在Groovy中重载BigDecimal的multiply方法

时间:2015-09-12 10:46:26

标签: math matrix groovy operator-overloading

我在Groovy中创建了一个类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

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

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

1 个答案:

答案 0 :(得分:2)

您可以重载multiply()BigDecimal中的ArrayList方法。扩展类将无法正常工作,因为Groovy不会从BigDecimalList文字创建子类的实例。

我的第一个建议是简单地坚持使用Matrix实例是multiply()方法的接收者的语法。例如: matrix.multiply(无论如何)。这是为了避免必须创建一堆重复的multiply()实现。防爆。 Matrix.multiply(BigInteger) BigInteger.multiply(Matrix)

一个例子

无论如何,这是一个如何将矩阵数学方法添加到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类别。我选择了一个Category来将multiply()实现保存在一个类中。

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