假设我为我的类定义了一些运算符,如下所示:
class A {
def +(f: Float) = /* ... */
}
val a: A = new A
这让我可以做到a + 1f
,很容易。如果我想让 lib 的用户也能够写1f + a
怎么办?我该如何实施?
假设我为我的类定义了一些运算符,如下所示:
class A {
def +(f: Float) = /* ... */
}
val a: A = new A
这让我可以做到a + 1f
,很容易。如果我想让 lib 的用户也能够写1f + a
怎么办?我该如何实施?
在 Scala 2.9 中,您可以导入此隐式转换:
implicit def floatPlusAExtender (x: Float) =
new {
def + (a: A) = a + x
}
并随心所欲地使用它。从 Scala 2.10 开始,您最好像这样进行转换:
implicit class FloatPlusAExtender (x: Float) {
def + (a: A) = a + x
}
甚至更好的是:
implicit class FloatPlusAExtender (val x: Float) extends AnyVal {
def + (a: A) = a + x
}
最后一种方法称为值类,与前两种不同,它以零开销提供此功能。(谢谢,axel22)这也是2.10自带的新东西
或者你可以A
像这样修改:
class A {
def + (x: Float) = /* ... */
def +: (x: Float) = this + x
}
并像这样使用它:
1f +: a
最后一种方法更可取。
一种方法是pimp-my-library-pattern:
class FloatWithPlusA(f: Float) {
def +(a: A) = a + f
}
implicit def floatPlusA(f: Float): FloatWithPlusA =
new FloatWithPlusA(f)
val a: A = new A
a + 1.0f /* a.+(1.0f) */
1.0f + a /* floatPlusA(1.0f).+(a) */
另一种方法是添加右关联方法,但明显的缺点是两个运算符的语法不同:
class A {
val f: Float = 1.0f
def +(f: Float) = this.f + f
def +:(f: Float) = this.f + f
}
val a: A = new A
a + 1.0f
1.0f +: a