我正在尝试修改扩展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 lib可以解决我的问题。
答案 0 :(得分:0)
当我使用scala REPL编译代码时,我得到了这个:
<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)。