我试图修改扩展Enterprise类型的StarShip特性。
(我对不知道这个题目的正确名称表示歉意,但我会在理解答案后更新它。)
由于某些原因,我无法获得传递的starShip参数。我评论了我得到错误的地方。
演示这一点的简单示例:
object Test {
trait Akira extends StarShip
trait Enterprise extends StarShip
sealed trait StarShip {
val captain: String
}
def doSomething[T: StarShip](starShip: T): T =
new T {
val captain = starShip.captain // Error: Cannot resolve symbol
}
doSomething(new Enterprise {
override val captain = "Picard"
})
}因为我要传递Enterprise的一个对象,所以我希望得到相同的类。
编辑:刚刚意识到我希望将传递给新类的starShip中的所有变量复制到新类中。除了我将修改其中的几个。
我相信Monocle解放会解决我的问题。
发布于 2015-09-09 08:35:11
当我用scala编译您的代码时,我得到以下内容:
<console>:17: error: Test.StarShip does not take type parameters
def doSomething[T: StarShip](starShip: T): T =
^
<console>:18: error: class type required but T found
new T {
^
<console>:19: error: value captain is not a member of type parameter T
val captain = starShip.captain // Error: Cannot resolve symbol
^
<console>:18: error: type mismatch;
found : T{}
required: T
new T {
^正如@dcastro所提到的,您可能希望在T上绑定一个类型,但是,即使修复这个语法错误也不够好,因为:
scala> def doSomething[T <: StarShip](starShip : T) : T = new T { val captain = starShip.captain }
<console>:8: error: class type required but T found不可能从类型参数实例化对象,因为编译器直到运行时才知道要实例化的实际类型。它可以是任何东西,包括在编译该函数之后编写的类型。
基于对doSomething的调用,我认为您根本不需要类型参数或实例化。也就是说,这是可行的:
scala> def doSomething[T <: StarShip](starShip : T) : T = { val captain = starShip.captain; starShip }
doSomething: [T <: StarShip](starShip: T)T
scala> doSomething(new Enterprise { val captain = "Kirk" })
res0: Enterprise = $anon$1@26653222因此,我认为通过以上的调整,你已经完成了你的目标。您已经修改了您的特性(StarShip),使企业具有船长成员的超越性值。
https://stackoverflow.com/questions/32468064
复制相似问题