我开始学习Scala,我将做一个简单的交叉编译器。
我会支持一些像print这样的指令。
注意:代码片段未经过测试或编译 这是我在JAVA中所做的。
public interface Compiler{
String getPrintInstruction();
}
public class JavaCompiler implements Compiler{
public String getPrintInstruction(){
return "System.out.print(arg0);"
}
}
public class ScalaCompiler implements Compiler{
public String getPrintInstruction(){
return "print(arg0);"
}
}
代码段是否在正确的“Scala方式”下方?
trait Compiler {
var printInstruction: String
}
class JavaCompiler extends Compiler {
var printInstruction = "System.out.print(arg0);"
}
class ScalaCompiler extends Compiler {
var printInstruction = "print(arg0);"
}
修改
我会将我的第二个问题转移到一个新的主题。
答案 0 :(得分:2)
对于1:1映射,这些var
应更改为def
s。
trait Compiler {
def printInstruction: String
}
class JavaCompiler extends Compiler {
def printInstruction = "System.out.print(arg0);"
}
class ScalaCompiler extends Compiler {
def printInstruction = "print(arg0);"
}
def
声明了一种方法。当您不提供实现时,它将成为一种抽象方法。
修改强>
这里使用的技术是一种有效且有用的技术。或者,您可以使用以下两种技术之一来模拟您的问题。
1)受歧视的工会。 (又名总和类型。)
请参阅this excellent article以了解此概念。这就是你的例子在以这种方式建模时的样子:
sealed trait Compiler {
def printInstruction: String = this match {
case JavaCompiler => "System.out.print(arg0);"
case ScalaCompiler => "print(arg0);"
}
}
case object JavaCompiler extends Compiler
case object ScalaCompiler extends Compiler
2)输入类模式。
Here是Daniel Sobral关于此主题的精彩文章。您可以通过Google搜索术语类型类,模式,Scala,implicits等来挖掘更多内容。如果问题是使用类型类模式建模的话,这就是您的代码的样子:
trait Compiler[C] {
def printInstruction(c: C): String
}
case object JavaCompiler
implicit object JavaCompilerIsCompiler extends Compiler[JavaCompiler.type] {
def printInstruction(c: JavaCompiler.type): String = "System.out.print(arg0);"
}
case object ScalaCompiler
implicit object ScalaCompilerIsCompiler extends Compiler[ScalaCompiler.type] {
def printInstruction(c: ScalaCompiler.type) = "print(arg0);"
}
对于您的问题,原始方法和受歧视的联盟方法似乎是最好的建模解决方案。
答案 1 :(得分:1)
最惯用的方法是使用def
表示抽象属性,使用val
表示具体的只读属性。在统一访问原则下,val
可用于实现方法:
trait Compiler {
def printInstruction: String
}
class JavaCompiler extends Compiler {
val printInstruction = "System.out.print(arg0);"
}
class ScalaCompiler extends Compiler {
val printInstruction = "print(arg0);"
}
答案 2 :(得分:0)
当我在特征中声明变量时,为什么我必须再次在类中声明变量?
因为您声明了方法printInstruction
的签名,但您没有说出它的作用。在class
中,因为它不是abstract class
,所以应该定义所有函数。
顺便说一句,如果在每个实现中都应该这样做,你可以直接在printInstruction
中定义trait Compiler
。