斯卡拉:为什么不编译? [英] Scala: Why doesn't this compile?

查看:114
本文介绍了斯卡拉:为什么不编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于:

  class Foo [T] {
def get:T
}

class Bar
class FooBar extends Foo [Bar] {
def get = new Bar
}

object Baz {
def [T,U<:Foo [T]](foo:Class [U]):T = foo.newInstance.get
}

我应该可以这样做,对吧?

  Baz .something(classOf [FooBar])

奇怪的是这是抛出:

 推断的类型参数[Nothing,this.FooBar]不符合方法something的类型参数bounds [T,U<:this.Foo [T]] 

这很奇怪:S。顺便说一句,我在迁移一些与我在这里编写的代码相当的java代码时遇到了这个问题,它的工作正常。

已经遇到了Scala的类型推断更令人讨厌的限制之一!请参阅这个回答,以清楚地解释为什么编译器在这里窒息。



<你有一些选择。最简单的你可以自己提供类型:

  Baz.something [Bar,FooBar](classOf [FooBar])

但是这很烦人。如果你真的不关心 U ,你可以将它从类型参数列表中删除:



<$ p $ (foo:Class [_<:Foo [T]]):T = foo.newInstance.get
}

现在 FooBar 将在您的示例中被正确推断。您也可以使用上面链接中讨论的技巧:

  object Baz {
def something [T,U <%Foo [T]](foo:Class [U]):T = foo.newInstance.get
}

为什么这个工作有点棘手 - 关键是在视图边界被解除之后, T 不再存在出现在 U 的界限内。

Given:

class Foo[T] {
 def get: T
}

class Bar
class FooBar extends Foo[Bar] {
 def get = new Bar
}

object Baz {
    def something [T, U <: Foo[T]] (foo : Class[U]): T = foo.newInstance.get
}

I should be able to do something like this, right?

Baz.something(classOf[FooBar])

Strangely this is throwing:

inferred type arguments [Nothing,this.FooBar] do not conform to method something's type parameter bounds [T,U <: this.Foo[T]]

Which is weird :S. BTW I'm having this issue while migrating some java code that's equivalent to what I write here and it's working fine.

解决方案

You've run into one of the more annoying limitations of Scala's type inference! See this answer for a clear explanation of why the compiler is choking here.

You have a handful of options. Most simply you can just provide the types yourself:

Baz.something[Bar, FooBar](classOf[FooBar])

But that's annoyingly verbose. If you really don't care about U, you can leave it out of the type argument list:

object Baz {
  def something[T](foo: Class[_ <: Foo[T]]): T = foo.newInstance.get
}

Now FooBar will be inferred correctly in your example. You can also use a trick discussed in the answer linked above:

object Baz {
  def something[T, U <% Foo[T]](foo: Class[U]): T = foo.newInstance.get
}

Why this works is a little tricky—the key is that after the view bound is desugared, T no longer appears in U's bound.

这篇关于斯卡拉:为什么不编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆