通用特征的隐式转换
我正在实现一个数据结构,并希望用户能够使用任何类型作为密钥,只要他提供一个合适的密钥类型来包装它。我有这个关键类型的特征。这个想法是进行从基类型到键类型的隐式转换,反之亦然(实际上)仅使用基类型。该特征如下所示:
trait Key[T] extends Ordered[Key[T]] {
def toBase : T
// Further stuff needed for datastructure...
}
object Key {
implicit def key2base[T](k : Key[T]) : T = k.toBase
}
调用站点代码可能如下所示:
def foo[K <% Key[K]]( bar : Seq[K] ) = bar.sorted(0)
计划是 K
类型的值应隐式转换为已排序的 Key[K]
或排序on Key[K]
应该分别隐式使用,因此一切都应该正常。当然,没有办法在特征本身中实现隐式base2key
。或者是否存在,可能使用隐式传递的类清单?考虑到这一点,我找不到任何参考资料。
是否可以以某种方式静态断言任何扩展 Key[T]
的类型都将带有隐式转换 T =>键[T]
?遗憾的是,伴生对象不能有抽象方法。
假设这可行,整个企业是否可行,或者所述用例是否需要多个链式隐式转换? (正如我所读到的,链接不会发生。)
附录:通过上面的定义,我可以对 Node(key : K, ...)
的序列进行排序(在K <% Key[K]
),使用 sortWith(_.key <= _.key)
,但不使用 sortBy(_.key)
。因此,显然,从 K
到 Key[K]
的转换是隐式发生的,即使我从未在任何地方声明过它,但没有 OrderingKey[K]
上的 code> 隐式可用。这是怎么回事?
I am implementing a datastructure and want the user to be able to use any type as key as long as he provides a suitable key type wrapping it. I have a trait for this key type. The idea is to have implicit conversions from base to key type and the other way round to (virtually) just use the base type. The trait looks like this:
trait Key[T] extends Ordered[Key[T]] {
def toBase : T
// Further stuff needed for datastructure...
}
object Key {
implicit def key2base[T](k : Key[T]) : T = k.toBase
}
Call site code could look like this:
def foo[K <% Key[K]]( bar : Seq[K] ) = bar.sorted(0)
Plan is that values of type K
should be implicitly converted to Key[K]
which is ordered or the ordering on Key[K]
should be implcitly used, respectively, so everything should work out. Of course, there is no way to implement implicit base2key
in the trait itself. Or is there, maybe using implicitly passed class manifests? I could not find any references considering this.
Is it possible to somehow assert statically that any type extending Key[T]
will come with an implicit conversion T => Key[T]
? The companion object can not have abstract methods, sadly.
Assume this works out, is the entire enterprise feasible or will the stated use case need multiple chained implicit conversions, anyway? (Chaining does not happen, as I have read.)
Addendum: With above definition, I can sort a sequence of Node(key : K, ...)
(under K <% Key[K]
) by using sortWith(_.key <= _.key)
, but not using sortBy(_.key)
. So, obviously, the conversion from K
to Key[K]
happens implicitly, even though it is never declared anywhere by me, but there is no Ordering
on Key[K]
available implicitly. What is going on here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你问“是否有可能以某种方式静态断言任何扩展
Key[T]
的类型都将带有隐式转换T => Key[T]
?遗憾的是,不能有抽象方法。”但您的示例是静态断言:当您需要从
T
到Key[T]
的视图时,您在编译时断言只能调用foo< /code> 用于可以提升为键的类型。或者我误解了什么?
关于附录:您说您对“从
K
到Key[K]
的转换隐式发生感到惊讶,即使我从未在任何地方声明过它”。事情是,你确实声明了它:T <% Key[T]
(我在这里使用T
而不是K
,你似乎在这里混淆了基本 *T*ype 和 *K*ey 的概念吗?)。这与因此相同,当您执行
sortWith(_ <= _)
时,您将T
强制转换为Key[T]
(对于其中 < code><= 根据特征Ordered[Key[T]]
定义)。以您的 Node 为例,为什么不希望
有所帮助......
you ask "Is it possible to somehow assert statically that any type extending
Key[T]
will come with an implicit conversionT => Key[T]
? The companion object can not have abstract methods, sadly."but your example is a static assertion : when you require a view from
T
toKey[T]
, you assert at compile time that you may only callfoo
for types which can be lifted to keys. Or am i misunderstanding something?regarding the addendum: you say you are surprised that "the conversion from
K
toKey[K]
happens implicitly, even though it is never declared anywhere by me". thing is, you did declare it:T <% Key[T]
(I am usingT
here instead ofK
, you seem to be mixing up the notion of base *T*ype and *K*ey here?). This is identical tothus, when you do
sortWith(_ <= _)
you coerceT
intoKey[T]
(for which<=
is defined as per traitOrdered[Key[T]]
).taking your Node example, why not do
hope that helps...
这是您问题的可能解决方案(希望我正确理解您的要求):
在这种情况下,
Key[T]
是类型T
和Keyable[T] 的包装器
是类型调用,允许将类型T
转换为Key[T]
。我还展示了base2key
的样子。Here is possible solution to your problem (hope I understood your requirements correctly):
In this case
Key[T]
is wrapper for typeT
andKeyable[T]
is type calss that allows to convert typeT
toKey[T]
. I also showed howbase2key
can look like.在这个答案中,我会保留目前最好的版本以供参考。使用这个答案可以更加集中问题;根据 这个 < /a>.
Key
特征保持不变;我添加了一个特定的函数来进行说明:以下内容按预期工作(如果完成了 import Key._):
让我们假设我们有一个简单的 class Node[K](val key : K )。同样,事情按预期进行:
再举一个例子,假设此代码仅使用
Key[T]
接口:请注意,由于
map
生成Seq[直接Key[K]]
;排序不需要转换。现在,如果我们有Key
的正确实现,那么下面的内容应该可以工作:
但实际上,没有找到从
StringKey
到String
的转换:这很奇怪;如果使用泛型类型参数声明,则存在从
Key[String]
到String
的转换。In this answer, I will keep the currently best version for reference. Using this answer to more focused question; will be obsolete with 2.9 according to this one.
The
Key
trait remains unchanged; I add a specific function for illustration:The following works as expected (if
import Key._
is done):Let us assume we have a simple
class Node[K](val key : K)
. Again, things work as expected:For another example, assume this code using only the
Key[T]
interface:Note that this compiles since
map
yields aSeq[Key[K]]
directly; no conversion needed for sorting. Now, if we have a proper implementation ofKey
, saythe following should work:
But actually, the conversion from
StringKey
toString
is not found:This is strange; there is a conversion from
Key[String]
toString
, if declared with a generic type parameter.