Scala最近给我带来了很多麻烦,因为我在互联网上找不到信息。由于Scala用一组无限术语定义了自己的语言(我还不知道),因此很难获得信息。
我在StackOverflow上就Scala和Java之间的翻译提出了一些问题,在最后一个问题中我说我将放弃这种方法。然而,我想了解正在发生的事情。
想象一下Scala类:
abstract class Block(n: String) {
require(n != null)
val name = n
var log: ArrayList[String]
var inputs: ArrayList[Input[_]]
var outputs: ArrayList[Output[_]]
def newValue
}
到目前为止还不错。问题是:
我无法访问类字段(是的,我尝试了this.inputs()
)。可能是因为它是这样翻译的:
public abstract class pt.thesis.tiago.Block
extends java.lang.Object implements scala.ScalaObject{
public java.lang.String name();
public abstract java.util.ArrayList log();
public abstract void log_$eq(java.util.ArrayList);
public abstract java.util.ArrayList inputs();
public abstract void inputs_$eq(java.util.ArrayList);
public abstract java.util.ArrayList outputs();
public abstract void outputs_$eq(java.util.ArrayList);
public abstract void newValue();
public pt.thesis.tiago.Block(java.lang.String);
}
为什么每一件事都是抽象的?难道我不能像Java一样,只做我想要的东西是抽象的吗?
关于术语,我不认为Scala发明了那么多术语。这些术语可能来自你不熟悉的语言(Erlang、Haskell、ML等),或者在其他语言中没有得到太多讨论的概念,比如类型论。
这里的一般原则是Scala是一种非常规则的语言。事实上,Martin想让它变得更简单、更有规律。
在Java中,只有方法可以是抽象的。在Scala中,基本上类的任何成员都可以是抽象的。在Scala中,为了使一个项抽象化,您可以省略它的定义。因此,语句var log: ArrayList[String]
实际上创建了一个抽象的var,而不是用null
初始化的混凝土条。是的,这与您对Java的期望不同。但它使Scala作为一个整体成为了一种更加常规的语言。
abstract class Foo {
type SomeType // abstract type
val someVal: SomeType // abstract val
var someVar: SomeType // abstract var
def someMethod(v: SomeType) // abstract method
}
如果您真的想创建一个初始化为null
的字段,那么就用_
初始化它。这将创建具体的变量,而不是抽象的变量。
每一件事都不是抽象的:名称不是抽象的。
事实上,由于它是一个抽象类,您可以有一些已声明但未定义的值,这些值本身将被标记为抽象。因此,如果你不想"输入"是抽象的,只需定义它们:
var inputs = ArrayList[Input[_]]()
编辑:关于评论中的常规问题,您仍然可以使用默认值(将为空):
abstract class Input[Type]{
var value:Type = _;
}
看看这意味着什么"分配"_"到scala中的字段?以及获取更多信息的最佳答案。