Scala Basic Literals
- Integer , Float , Boolean
- Symbol
这个Symbol变量第一次见,特意花时间研究一下。
Symbol 是Scala中所谓literal类型的一种,literal字面意思为文本,表现为可以直接在代码中写为常量值的东西。
Symbol 本质上是字符串的再封装,相同值(名字)的Symbol具有相同的instance,而相同名字(也是值)的字符串并不一定是同一个instance。
如某字符串反复出现,而且值不会改变,那么,可以使用Symbol,但其实并不必须,同样可以使用字符串的变量名称。
相比较于String类型,Symbol类型有两个比较明显的特点:节省内存和快速比较。为了理解,让我们先来了解一下Java中String的intern()方法。
Oracle的开发文档上讲解的很详细:String类内部维护一个字符串池(strings pool),当调用String的intern()方法时,如果字符串池中已经存在该字符串,则直接返回池中字符串引用,如果不存在,则将该字符串添加到池中,并返回该字符串对象的引用。执行过intern()方法的字符串,我们就说这个字符串被拘禁了(interned)。默认情况下,代码中的字符串字面量和字符串常量值都是被拘禁的,例如:
String s1 = "abc";
String s2 = new String("abc");
//返回true
System.out.println(s1 == s2.intern());
String s2 = new String("abc");
String s3 = new String("abc");
//返回true
System.out.println(s2.intern() == s3.intern());
//返回false
System.out.println(s2 == s3);
在Scala中,Symbol类型的对象是被拘禁的(interned),任意的同名symbols都指向同一个Symbol对象,避免了因冗余而造成的内存开销。而对于String类型,只有编译时确定的字符串是被拘禁的(interned)。Scala测试代码如下:
val s = 'aSymbol
//输出true
println( s == 'aSymbol)
//输出true
println( s == Symbol("aSymbol"))
虽然两者结果相同都返回true,但是由于Symbol类型的对象是被拘禁的(interned),任意的同名symbols都指向同一个Symbol对象,而不同名的symbols一定指向不同的Symbol对象,所以symbols对象之间可以使用操作符==快速地进行相等性比较,常数时间内便可以完成,而字符串的equals方法需要逐个字符比较两个字符串,执行时间取决于两个字符串的长度,速度很慢。(实际上,String.equals方法会先比较引用是否相同,但是在运行时产生的字符串对象,引用一般是不同的)
Symbol类型一般用于快速比较,例如用于Map类型:Map<Symbol, Data>,根据一个Symbol对象,可以快速查询相应的Data, 而Map<String, Data>的查询效率则低很多。
Variable Declaration
scala有两种变量类型,var和val
var myVar : String = "Foo"
var是可变的。
val myVal : String = "Foo"
val是不可变的。
当你不指示变量类型,可以使用默认。系统自动帮你确认类型。
var myVar = 10;
val myVal = "Hello, Scala!";
scala也支持tuple对象来定义对象。
val (myVar1: Int, myVar2: String) = Pair(40, "Foo")
val (myVar1, myVar2) = Pair(40, "Foo")
scala class
定义类
import java.io._
#定义类
class Point(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("Point x location : " + x);
println ("Point y location : " + y);
}
}
#main function
object Demo {
def main(args: Array[String]) {
val pt = new Point(10, 20);
// Move to a new location
pt.move(10, 10);
}
}
在scala console中想要执行,需要先编译,在执行
\>scalac Demo.scala
\>scala Demo
类的继承
import java.io._
class Point(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("Point x location : " + x);
println ("Point y location : " + y);
}
}
#location是Point的子类。
class Location(override val xc: Int, override val yc: Int,
val zc :Int) extends Point(xc, yc){
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("Point x location : " + x);
println ("Point y location : " + y);
println ("Point z location : " + z);
}
}
object Demo {
def main(args: Array[String]) {
val loc = new Location(10, 20, 15);
// Move to a new location
loc.move(10, 10, 5);
}
}