我在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
这两行产生错误,因为类BigDecimal
和ArrayList
不能乘以Matrix
。
有没有办法为这些类重载multiply()
? (我知道我可以扩展这两个类,但是有没有办法告诉Groovy在编译代码时使用扩展类?)
答案 0 :(得分:2)
您可以重载multiply()
和BigDecimal
中的ArrayList
方法。扩展类将无法正常工作,因为Groovy不会从BigDecimal
和List
文字创建子类的实例。
我的第一个建议是简单地坚持使用Matrix
实例是multiply()
方法的接收者的语法。例如: matrix.multiply(无论如何)。这是为了避免必须创建一堆重复的multiply()
实现。防爆。 Matrix.multiply(BigInteger)和 BigInteger.multiply(Matrix)。
无论如何,这是一个如何将矩阵数学方法添加到BigDecimal
和List
的示例:
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>
作为矩阵。