使用Scala泛型时出现意外的类型不匹配
我有一个简单的场景,在使用Scala泛型时会产生类型不匹配,现在还不清楚为什么或者如何解决它使用Scala泛型时出现意外的类型不匹配,scala,generics,Scala,Generics,我有一个简单的场景,在使用Scala泛型时会产生类型不匹配,现在还不清楚为什么或者如何解决它 trait Foo case class Bar() extends Foo trait FooGetter[T <: Foo] { def get: T = Bar() // Error } trait Foo case类Bar()扩展了Foo trait FooGetter[T您可以像这样简化代码: trait Foo case class Bar() extends Foo tra
trait Foo
case class Bar() extends Foo
trait FooGetter[T <: Foo] {
def get: T = Bar() // Error
}
trait Foo
case类Bar()扩展了Foo
trait FooGetter[T您可以像这样简化代码:
trait Foo
case class Bar() extends Foo
trait FooGetter {
def get: Foo = Bar()
}
FooGetter
与Foo
紧密相连。无论如何,将FooGetter
设置为通用是没有意义的。(注意,Bar
是scala类型检查器的Foo
。始终有效的是的安装,在您的示例中:
trait Foo
case class Bar() extends Foo
trait FooGetter[T <: Foo] {
def get: T = Bar().asInstanceOf[T]
}
但正如赛斯·蒂苏所指出的那样:
如果生成的代码不正确,那么使用泛型就毫无意义
实际上是通用的
这里T您声明T
是Foo
的子类型,而Bar
是Foo
的子类型。这并不保证它将是Foo
的任何子类型。例如,如果您创建了另一个类Bazz
,它也从Foo
扩展,并尝试创建的实例e> FooGetter
在Bazz
中参数化,则get上的Bar
实例将是类型错误匹配。@LuisMiguelMejíaSuárez我希望能够返回Bar()
在我的方法中。在这种情况下,我应该如何声明编译?您可以只更改类型签名以返回一个条
,但是类型参数和特征本身就变得不必要了。我认为您真正想要的是能够通过调用类似F的东西隐式地获得Foot的正确实例ooGeter[Bar].get
。我认为您应该编辑该问题以更好地解释主要问题,并提供尽可能多的详细信息。如果您希望所有返回的内容都像Foo
一样处理,为什么不将返回类型指定为Foo
?您仍然可以返回Bar()
在实现中,但对于FooGetter
界面的用户来说,它将是任何Foo
谢谢-它是通用的,因为它是对实际getter的简化,而实际getter是子类化的,并用于其他类型,所以在我的情况下需要它。在这种情况下,你能详细说明这个问题吗?这给了我一个例外Scalafiddle-请注意,newfoogetter[Bar]{}
是非法的,因为T>:Foo
意味着这里不允许使用Bar
。我的答案是试图找出问题中不允许隐式强制转换的原因;上限或下限的使用不是我的重点。好吧,但是我的示例看起来会是什么样子-你能在ScalaFiddle中创建一个新版本吗?请ee.我的回答可能有点误导-请你解释一下为什么不应该使用来代替[T]
-或者为什么你投了反对票-我在这里学习,Josh Stone仍然没有正确的答案。你可以用替代来解决任何类型的不匹配。我不认为这算是一个解决方案,因为生成的代码完全是错误的,它恰好在条
的情况下工作,但总体上是错误的,没有任何意义如果所得到的代码不是真正通用的,那么使用泛型就行了。至于我认为合适的答案,“陈中铺的答案似乎和任何人都能做的一样好,没有更多的上下文来说明真正的问题是如何解决的。”埃里克的回答和评论。希望这有帮助。国家-我同意你的观点并调整了我的答案。
println(new FooGetter[Bar]{}.get) // Bar()
trait FooGetter[T >: Foo] {
def get: T = Bar()
}