我想为内置类型(例如Double)添加一个方法,以便我可以使用infix
运算符.那可能吗?
是的,不是.是的,你可以让它看起来像你已经添加了一个方法double
.例如:
class MyRichDouble(d: Double) { def <>(other: Double) = d != other } implicit def doubleToSyntax(d: Double) = new MyRichDouble(d)
此代码将以前不可用的<>
运算符添加到任何类型的对象Double
.只要该doubleToSyntax
方法在范围内,以便可以无限制地调用它,以下方法将起作用:
3.1415 <> 2.68 // => true
答案的"否"部分来自于你并没有真正在Double
课堂上添加任何内容.相反,您正在创建Double
从新类型转换,它确定了您想要的方法.这可能是一种比许多动态语言提供的开放类更强大的技术.它也恰好是完全类型安全的.:-)
您应该注意的一些限制:
此技术不允许您删除或重新定义现有方法,只需添加新方法即可
隐式转换方法(在这种情况下,doubleToSyntax
)绝对必须在范围内,以使所需的扩展方法可用
在惯用语中,隐式转换要么放在单个对象中并导入(例如import Predef._
)或在特征内并且继承(例如class MyStuff extends PredefTrait
).
稍微说一下:Scala中的"中缀运算符"实际上就是方法.与<>
允许它为中缀的方法没有任何关联,解析器只是以这种方式接受它.如果您愿意,也可以使用"常规方法"作为中缀运算符.例如,Stream
该类定义了一个take
方法,该方法接受一个Int
参数并返回一个新参数Stream
.这可以通过以下方式使用:
val str: Stream[Int] = ... val subStream = str take 5
的str take 5
表达是从字面上相同str.take(5)
.