【发布时间】:2017-11-30 14:37:13
【问题描述】:
我知道 scala 允许对其默认运算符 (+, - ! etc.) 进行重载。是否可以定义自定义运算符并制作类似 |.| 的东西运算符,以便 | -3|计算结果为 3。或者定义像 ++++ 这样的运算符,使 a ++++ b 等于 a+3*b?
【问题讨论】:
标签: scala operator-overloading operators
我知道 scala 允许对其默认运算符 (+, - ! etc.) 进行重载。是否可以定义自定义运算符并制作类似 |.| 的东西运算符,以便 | -3|计算结果为 3。或者定义像 ++++ 这样的运算符,使 a ++++ b 等于 a+3*b?
【问题讨论】:
标签: scala operator-overloading operators
你应该看看scala operators documentation。
您可以轻松地制作 ++++ 运算符,而不是 |.|运算符。
scala 中的运算符只是具有非字母数字名称的函数。由于 scala 还支持将 a.f(b) 作为 a f b 调用,因此您可以实现第一个行为。例如:
case class A(v: Int) {
def ++++(b: A): A = A(v + 3 * b.v)
}
val a = A(1)
val b = A(2)
a ++++ b
>> A(7)
a.++++(b) // just another way of doing the exact same call
如果您想将它添加到整数,您只需创建一个隐式类来添加它。
另一种选择是为运算符添加前缀,例如考虑使用 -a 来获得否定值。没有“第一个元素”可以将 - 应用到,而是 - 应用到 a(参见 this answer)。
例如:
case class A(v: Int) {
def unary_!(): Int = -v
}
val a = A(3)
!a
>> -3
正在做|.|有两个问题:首先,运营商有两个部分,即它是分裂的。二是使用|
为了做一个两部分的操作符(比如!.!),你可能想要生成一些私有类型并从一个中返回它!然后用它作为另一个的输入来返回输出类型。
第二个问题是使用 |这是一个非法字符。查看this answer 获取合法字符列表
【讨论】:
| 是合法的,并且在您链接的答案中被列为合法。
class A { def |(int: Int) = int * 2; def ||(int: Int) = int * 3; def |||(int: Int) = int * 4 }; new A || 2 // returns 6。它不能作为 unary_| 工作,我相信只有 unary_- 和 unary_! 支持作为前缀运算符。
|x| 以 | 作为分隔符。它仍然可以完成,但不会笨拙。
一个扩展@assaf-mendelson答案的例子
case class Abs(a: Int) {
def !(): Int = a.abs
}
implicit def toAbs(a: Int) = new {
def unary_! : Abs = Abs(a)
}
然后
> val a = -3
a: Int = -3
> !a
res0: Abs = Abs(-3)
> !a!
res1: Int = 3
> val b = 12
b: Int = 12
> !b!
res2: Int = 12
> (!a!) + (!b!)
res3: Int = 15
我们不能将 abs 实现为 |a|,因为 unary_ 仅适用于 !、~、+ 和 -
【讨论】: