在Scala中你可以使用implicits进行Monkey Patching但昨天我在ruby中用Fixnum看到了这个例子,这是一个愚蠢的事情,但我想在scala中实现它
class Fixnum
def to_roman
'I'*self #only works until 3, but only for this purpose
end
def +(other)
self - other
end
end
puts 2.to_roman #This prints "II"
puts 1 + 1 #This prints 0
然而在scala中,我无法使用+(逆)方法
object TestImplicits extends App {
implicit class ReverseInt(val original: Int) extends AnyVal {
def toRoman = { "I" * original }
def +(other:Int){
original - other
}
}
println(5.toRoman) // prints IIIII
println( 5 + 3 ) // prints 8
}
另外,scala不像Ruby那样有全局猴子补丁吗?
答案 0 :(得分:2)
Scala只会尝试为未找到的方法找到隐式转换。由于Scala找到toRoman
方法,因此它不会尝试查找隐式转换,而不是Int
,其中Scala 不找到方法,因此将使用toRoman
方法搜索从select a.cekckInTime, b.CheckOutTime from
(select ROW_NUMBER() Over( ORDER BY CekckInTime ) as Id, * from attendancetable where cekckInTime is not null) a
inner join
(select ROW_NUMBER() Over( ORDER BY CheckOutTime ) as Id, * from attendancetable where CheckOutTime is not null) b
on a.Id =b.Id
到某种类型的隐式转换。
答案 1 :(得分:1)
这很接近:
class WrappedInt(val n: Int) {
def + (other: Int): Int = {
n - other
}
}
implicit def unpack(wi: WrappedInt): Int = {
wi.n
}
// usage
val wrapped = new WrappedInt(5)
println(wrapped + 3) // performs 5 - 3
println(wrapped * 2) // 5 * 2 (`unpack` is called first)
但请注意,如果将WrappedInt
传递给期望Int
的方法,则该方法将对展开的值进行操作,因此“patch”在该方法中不会处于活动状态:
def addOne(n: Int) = {
n + 1
}
println(addOne(new WrappedInt(5))) // Prints 6 (no patch)
我认为最好不要允许全局修补 - 这是非常危险的,因为没有任何迹象表明,如果你正在孤立地看一个类,那么已经修补了一些东西。项目中的每个人都需要学习和记忆所有这些无形的事情。如果您正在处理多个项目,则需要记住哪个项目有哪个补丁。使用Scala时,必须显式导入第三方隐含,因此在当前文件或范围中有一些指示表明存在特殊情况。
Ruby有优化,但是don't seem very popular,可能是因为修补在文化中是如此简单和根深蒂固。