我正在学习scala并创建了一个foo条形码来玩耍特性和Manifest。这是我的目标用途:
slang = new Slang()
slang.speak[MilitarySlang]("Private")
slang.speak[GanstaSlang]("Homie")
这是我的代码:
trait Foo {
val foo = "Foo'd Up "
trait Style {
def phrase(subject : String): String
}
def speak(someone: String): String
}
class Slang extends Foo {
class MilitarySlang extends Style {
def phrase(subject: String) = "Beyond All Recognition, " + subject
}
class GanstaSlang extends Style {
def phrase(subject: String) = "Fo Sheezy, " + subject
}
def speak[Foo with Style: Manifest](someone: String): String = {
val mbar = manifest[Foo with Style].erasure.newInstance().asInstanceOf[Foo with Style]
foo + mbar.phrase(someone)
}
}
我得到的当前错误是speak[Foo *with Style]
错误']'预期,但'找到'。
如何确保类型推断出必须使用样式扩展Foo的类
答案 0 :(得分:2)
这不会起作用......
slang = new Slang()
slang.speak[MilitarySlang]("Private")
... 1st因为你已经定义speak()
没有参数,而第2因为MilitarySlang
不在范围内(即从呼叫网站看不到)。
一个简单的解决方案(可能过于简单)是将Style
从类型参数移动到值参数。
在Foo
内,定义变为def speak(style: Style, subject: String): String
,而Slang
内的定义变为...... {/ p>
def speak(style: Style, subject: String): String =
foo + style.phrase(subject)
...可以像这样调用......
val slang = new Slang
slang.speak(new slang.MilitarySlang, "private")
// res0: String = Foo'd Up Beyond All Recognition, private
答案 1 :(得分:1)
您可以将Style拆分为单独的特征,但在Foo中使用自我类型。
trait Style {
def phrase(subject : String): String
}
trait Foo {
this: Style =>
val foo = "Foo'd Up "
def speak(): String
}
这将告诉编译器任何扩展Foo的东西都必须用Style扩展它。