在 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 BigDecimal
和 ArrayList
不能乘以 Matrix
.
有没有办法为这些 class 重载 multiply()
? (我知道我可以扩展这两个 classes,但是有没有办法告诉 Groovy 在编译代码时使用扩展的 classes?)
您可以在 BigDecimal
和 ArrayList
中重载 multiply()
方法。扩展 classes 不会像你希望的那样工作,因为 Groovy 不会从 BigDecimal
和 List
文字创建你的子classes 的实例。
我的第一个建议是简单地坚持 Matrix
实例是 multiply()
方法的接收者的语法。例如:matrix.multiply(随便)。这是为了避免必须创建一堆重复的 multiply()
实现。前任。 Matrix.multiply(BigInteger) 和 BigInteger.multiply(矩阵).
一个例子
无论如何,这是一个如何将矩阵数学方法添加到 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 类别。我选择了一个类别来将 multiply() 实现放在一个 class 中。
如果矩阵只是 List<List>
,请注意,使用这种方法实际上可以摆脱 Matrix
class。相反,您可以将所有 multiply()
实现放入 MatrixMath
类别,并使用 List<List>
作为矩阵。
我在 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 BigDecimal
和 ArrayList
不能乘以 Matrix
.
有没有办法为这些 class 重载 multiply()
? (我知道我可以扩展这两个 classes,但是有没有办法告诉 Groovy 在编译代码时使用扩展的 classes?)
您可以在 BigDecimal
和 ArrayList
中重载 multiply()
方法。扩展 classes 不会像你希望的那样工作,因为 Groovy 不会从 BigDecimal
和 List
文字创建你的子classes 的实例。
我的第一个建议是简单地坚持 Matrix
实例是 multiply()
方法的接收者的语法。例如:matrix.multiply(随便)。这是为了避免必须创建一堆重复的 multiply()
实现。前任。 Matrix.multiply(BigInteger) 和 BigInteger.multiply(矩阵).
一个例子
无论如何,这是一个如何将矩阵数学方法添加到 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 类别。我选择了一个类别来将 multiply() 实现放在一个 class 中。
如果矩阵只是 List<List>
,请注意,使用这种方法实际上可以摆脱 Matrix
class。相反,您可以将所有 multiply()
实现放入 MatrixMath
类别,并使用 List<List>
作为矩阵。