相同的方法,不同的参数类型,一次实现
我有一个(Java)类,其操作如下:
abstract class Holder {
def set(i: Int): Unit
def set(s: String): Unit
def set(b: Boolean): Unit
...
}
本质上,所有类都执行相同的任务,但只是采用不同的参数类型。我很想创建一个通用的 Accessor[T] 来执行类似的操作:
class Accessor[T](holder: Holder) {
def set(value: T) { holder.set(value) }
}
...但这给出了:
<console>:16: error: overloaded method value set with alternatives:
(s: String)Unit <and>
(i: Int)Unit
(b: Boolean)Unit
cannot be applied to (T)
def set(value: T) { holder.set(value) }
有什么出路吗?
I have a (Java) class with operations like this:
abstract class Holder {
def set(i: Int): Unit
def set(s: String): Unit
def set(b: Boolean): Unit
...
}
Essentially, the all perform the same task, but just take different argument types. I would love to create a generic Accessor[T] that performs something like this:
class Accessor[T](holder: Holder) {
def set(value: T) { holder.set(value) }
}
... but that gives:
<console>:16: error: overloaded method value set with alternatives:
(s: String)Unit <and>
(i: Int)Unit
(b: Boolean)Unit
cannot be applied to (T)
def set(value: T) { holder.set(value) }
Is there any way out?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用反射。
Scala 中有一个实验性的快捷方式,但在 2.8.0 发布之前它被删除了。
Use reflection.
There was an experimental shortcut for that in Scala, but it got removed before 2.8.0 was released.
我认为匹配应该很好
I think matching should work nicely
我不完全理解你的用例,但是你可能会尝试做的一件事——如果性能不是最重要的——是创建一个包装类,为你转换为通用形式,然后让你的所有方法都采用该包装类(具有适当的隐式转换)。例如:
这有点像采用
Any
,只不过您可以根据自己的喜好限制类型,并指定转换为您想要的任何通用表示形式。但是,如果不存在通用形式,那么我不确定您的意思是代码每次都在执行相同的操作。 (也许您的意思是您可以设想一个自动生成代码的宏(或另一个程序)——Scala 没有内置这种支持,但您当然可以编写一个生成 Scala 代码的 Scala 程序。)I don't fully understand your use case, but one thing that you might try doing--if performance is not of utmost importance--is creating a wrapper class that converts to a universal form for you, and then have all your methods take that wrapper class (with appropriate implicit conversions in place). For example:
This is a little bit like taking an
Any
except that you can restrict the types however you like and specify the conversion into whatever universal representation you have in mind. However, if there does not exist a universal form, then I'm not sure in what sense that you mean the code is doing the same thing each time. (Maybe you mean that you can conceive of a macro (or another program) that would generate the code automatically--Scala doesn't have that support built in, but you can of course write a Scala program that produces Scala code.)回顾到目前为止收集到的结果,建议了几个解决方案:
更准确地说,整个练习就是围绕京都内阁编写一个包装。京都内阁具有将字节数组键与字节数组值以及字符串键与字符串值关联的方法。然后它基本上复制了处理字节数组和字符串的键和值的大部分操作。
为了围绕京都橱柜的 DB 类创建 Map 包装器,我定义了一个特征 TypedDBOperations[T],其中 T 是参数类型,并实现了两次。如果我现在构造一个 Map[Array[Byte], Array[Byte]],隐式转换将自动为其分配正确的 TypedDBOperations 实例,调用 DB 类的基于 Array[Byte] 的操作。
这是我一直在谈论的特征:
这些是两种类型的键值组合的实现:
不是有史以来最令人满意的解决方案,但它完成了工作。再次注意,仍然存在相当多的重复,但似乎没有办法消除它。
Looking back at the results gathered so far, there are a couple of solutions suggested:
To be a little more precise, the whole exercise was about writing a wrapper around Kyoto Cabinet. Kyoto Cabinet has methods for associating byte array keys with byte array values and String keys with String values. And then it basically replicates most of the operations for dealing with keys and values for both byte array as well as Strings.
In order to create a Map wrapper around Kyoto Cabinet's DB class, I defined a trait TypedDBOperations[T], with T being the type of parameter, and had it implemented twice. If I now construct a Map[Array[Byte], Array[Byte]], an implicit conversion will automatically assign it the proper instane of TypedDBOperations, calling the Array[Byte] based operations of the DB class.
This is the trait that I have been talking about:
And these are the implementations for both type of key value combinations:
Not the most satisfying solution ever, but it gets the job done. Again, note there still is quite a bit of duplication, but it seems there's no way to get rid of it.