变量
变量不过是保留的内存空间,定义一个变量变在内存里开辟了一块空间,其类型决定它 的大小和能赋值什么类型。
变量声明
scala的变量分为var
和val
分别代表mutable variable
和immutable variable
1 2
| var myVar : String = "Foo" val myVal : String = “Foo”
|
变量数据类型
变量的类型指定于变量名与等号=
之间
1
| var or val VariableName : DataType = [Initial Value]
|
也可以不指定初始值
1 2
| var myVar :Int; val myVal :String;
|
变量类型推断
编译器能够根据声明时的初始值来推断变量类型,称为类型推断
1 2
| var myVar = 10; //Int val myVal = "Hello, Scala!";//String
|
Multiple assignment
如果一段代码返回一个元组(多个不同类型对象的集合),元组可被赋值给val
变量
1
| val (myVar1: Int, myVar2: String) = Pair(40, "Foo")
|
类型推断也适用
1
| val (myVar1, myVar2) = Pair(40, "Foo")
|
例程
以下例程展示变量声明
1 2 3 4 5 6 7 8 9
| object Demo { def main(args: Array[String]) { var myVar :Int = 10; val myVal :String = “Hello Scala with datatype declaration.”; var myVar1 = 20; val myVal1 = “Hello Scala new without datatype declaration.”; println(myVar) println(myVal) println(myVar1) println(myVal1) } }
|
编译执行
1 2
| scalac Demo.scala scala Demo
|
输出为
1 2 3 4
| 10 Hello Scala with datatype declaration. 20 Hello Scala without datatype declaration.
|
变量范围
三种:域、方法参数和局部变量。
域
属于对象,对象的所有方法都可访问,对外权限取决于存取修饰符
/‘access modifier’。可以是var
也可以是val
。
方法参数
用于在调用方法里向方法内部传递值。其值只在方法方法内部可见,但如果参数是对象且外部也有外用,则外部亦可见。方法参数总是val
,亦即immutable
。
局部变量
定义于方法内部,也只在内部可见,但如果将其引用return
,则可以逃离本函数范围 。可是是var
或者val
.
类和对象
以下是一个基本定义类的语法。
1 2 3 4 5 6 7 8 9 10
| class <classsname>(xc: Int, 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); } }
|
类名可作为构造函数,它带有两上参数,在整个类中可见。通过new
关键字创建类的对象,并可使用如示例中的方法访问对象的域和方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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); } } object Demo { def main(args: Array[String]) { val pt = new Point(10, 20); // Move to a new location pt.move(10, 10); } }
|
继承
scala也可以用extends
关键字继承类,但有两个限制:1、重载方法需要override
关键字;2、只有primary
构造方法可以向基类的构造方法传递值。
scala也是单继承
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Location(override val xc: Int, override val yc: Int, val zc :Int) extends Point(xc, yc){ var z: Int = zc //move并非重载,签名不同 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); } }
|
隐式类 implicit class
隐式类允许隐式地与方法的主构造方法通信,使用implicit
关键字标识,这个特性是从2.10才引入的。
语法: 以下是一个隐式类的语法示意。这个隐式类总是对象的访问范围,从而所有方法都可用,因为隐式类不能位于最外层。
1 2 3 4 5
| object <object name> { implicit class <class name>(<Variable>: Data type) { def <method>(): Unit= } }
|
以下的例子定义了一个隐式类IntTimes
,它一个times()
方法,该方法有一循环来执行指定语句和指定次。让我来打印四次hello world
以下例程中使用了两个object class
,因此需要将它们保存在两个文件中。
Run.scala
1 2 3 4 5 6 7 8 9 10 11 12
| object Run { implicit class IntTimes(x: Int) { def times[A](f: => A): Unit = { def loop(current: Int): Unit = if (current > 0) { f loop(current - 1) } loop(x) } } }
|
Demo.scala
1 2 3 4 5 6 7
| import Run._ object Demo { def main(args: Array[String]) { 4 times println("hello world") } }
|
运行效果:
1 2 3 4 5 6 7
| $ scalac Run.scala $ scalac Demo.scala $ scala Demo hello world hello world hello world hello world
|
- 隐式类必须定义于其它类/对象/物质内部(不能是最外层)
- 其构造方法只能接受一个非隐式参数
- 不能与作用域内的其它方法、成员或对象同名
单例对象Singleton Objects
scala中无静态成员,但有单例对象
/Singleton Objects
:只有一个实例/对象的类。使用object
而不是class
创建,无法实例化而只能通过主构造方法传递参数。之前例子中scala的main方法都是用单例对象调用的。
请返回重温Point类的例子