集合如何对元素类型使用隐式转换?

发布于 2024-10-15 16:51:34 字数 758 浏览 2 评论 0原文

在处理这个问题时,我遇到了以下问题。考虑两个方法定义:

def foo[T <: Ordered[T]](s : Seq[T]) = s.sorted

def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted

第一个可以编译,第二个则不能。编译器不知道它可以使用断言的隐式转换来获取Ordering。如果我们提供一点帮助,它就会起作用:

def foo[T <% Ordered[T]](s : Seq[T]) = s.sortWith(_<=_)

在编译匿名函数时,编译器应用隐式转换来查找方法<=,一切都很好。

我没有另一个例子,但可以想象类似的问题会发生在集合上的其他函数中,这些函数要求元素具有某些属性,如果这些属性只能通过转换来断言的话。

编译器受到这种限制是否有特殊原因?没有通用的方法来解决此类问题吗? (这里看起来很简单。)是否有解决方法,例如另一个将 Key[T] 上的属性转换为 T 的隐式转换?

(请注意,如果 T 的具体值最终具有该属性,则最后一个想法可能会出现问题;然后我们会遇到不明确的情况)。

While working on this question, I came up with the following issue. Consider two method definitions:

def foo[T <: Ordered[T]](s : Seq[T]) = s.sorted

def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted

The first one compiles, the second does not. The compiler does not figure out that it can use the asserted implicit conversion to get an Ordering. If we help a bit, it works:

def foo[T <% Ordered[T]](s : Seq[T]) = s.sortWith(_<=_)

While compiling the anonymous function the compiler applies the implicit conversion to find method <=, everything is fine.

I do not have another example, but can imagine similar issues to happen with other functions on collections that require elements to have certain properties, if those can only be asserted via conversion.

Is there a particular reason why the compiler is restricted this way? Is there no general way to resolve such issues? (Here it seems easy.) Is there a workaround, e.g. another implicit conversion that translates the property on Key[T] to T?

(Note that the last idea can be problematic if a concrete value for T ends up having the property; we then get an ambiguous situation).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘亓 2024-10-22 16:51:34
scala> implicit def ordering[T <% Ordered[T]] = new Ordering[T]{def compare(x: T, y: T) = x compare y}
ordering: [T](implicit evidence$1: (T) => Ordered[T])java.lang.Object with Ordering[T]

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
foo: [T](s: Seq[T])(implicit evidence$1: (T) => Ordered[T])Seq[T]
scala> implicit def ordering[T <% Ordered[T]] = new Ordering[T]{def compare(x: T, y: T) = x compare y}
ordering: [T](implicit evidence$1: (T) => Ordered[T])java.lang.Object with Ordering[T]

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
foo: [T](s: Seq[T])(implicit evidence$1: (T) => Ordered[T])Seq[T]
雨落星ぅ辰 2024-10-22 16:51:34
% scala29
Welcome to Scala version 2.9.0.r24168-b20110202012927 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
foo: [T](s: Seq[T])(implicit evidence$1: (T) => Ordered[T])Seq[T]

scala>

顺便说一句,“这似乎很容易”,但事实并非如此。像这样的隐含者喜欢分歧,而且他们非常坚定。

% scala29
Welcome to Scala version 2.9.0.r24168-b20110202012927 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
foo: [T](s: Seq[T])(implicit evidence$1: (T) => Ordered[T])Seq[T]

scala>

By the way, re "here it seems easy", it wasn't. Implicits like these enjoy diverging and they were pretty determined.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文