http://www.runoob.com/scala/scala-data-types.html
scala api:
http://www.scala-lang.org/api/current/scala/Nothing.html
http://blog.csdn.net/bluishglc/article/details/55668192
运算优先级:
在Scala里所有以“:”结尾的运算符是右关联的,其他的运算符都是左关联的
数据类型
1 | // Byte,Int,Short,Long等略. |
Nothing和Unit的区别:
- Unit有一个值 ()
Nothing没有值.- 以Unit为返回值的话,方法能正常结束;
以Nothing为返回值的话,方法只能以异常退出.
http://blog.csdn.net/bluejoe2000/article/details/30465175
变量与常量:
val
value,值. 定义时立即求值. (饿汉求值). 只求一次.
var
variable,变量. 定义时立即求值. 可改变赋值. 只求一次.
def
define. 每次使用时才求值.(惰性求值). 求N次
lazy val
懒求值. 第一次使用时求值,但只求一次.
退出cli
:q 或 sys.exit
查看版本:
scala –version
访问修饰符
private: Scala 中的 private 限定符,比 Java 更严格,在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员。
1 | class Outer{ |
protected:在 scala 中,对保护(Protected)成员的访问比 java 更严格一些。因为它只允许保护成员在定义了该成员的的类的子类中被访问。而在java中,用protected关键字修饰的成员,除了定义了该成员的类的子类可以访问,同一个包里的其他类也可以进行访问。
1 | package p{ |
public: 任何地方都可以被访问
private[x],protected[x]:这里的x指代某个所属的包、类或单例对象。如果写成private[x],读作”这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对象可见外,对其它所有类都是private。
这种技巧在横跨了若干包的大型项目中非常有用,它允许你定义一些在你项目的若干子包中可见但对于项目外部的客户却始终不可见的东西。
1 | package bobsrocckets{ |
上述例子中,类Navigator被标记为private[bobsrockets]就是说这个类对包含在bobsrockets包里的所有的类和对象可见。
比如说,从Vehicle对象里对Navigator的访问是被允许的,因为对象Vehicle包含在包launch中,而launch包在bobsrockets中,相反,所有在包bobsrockets之外的代码都不能访问类Navigator。
1 | class Student{ |
下划线的用法
1 | // 1、作为“通配符”,类似Java中的*。如 |
https://my.oschina.net/leejun2005/blog/405305
scala的函数和方法:
Scala 有函数和方法,二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。
1 | 函数也类似于一个变量,类似函数指针的概念. |
传参:
1 | //传值调用(call-by-value):先计算参数表达式的值,再应用到函数内部; |
List符号函数
优先使用
++
而不是:::
;
优先使用+:
而不是::
;
冒号靠近List.
actor
http://www.cnblogs.com/vikings-blog/p/3942417.html
函数和方法,def和val区别:
http://www.jianshu.com/p/9b9519a36d78
经测试,scala是从Function0定义到了Function22;
而没有Function23,因此函数对象最多22个参数.
object和class的区别
class
中均为实例成员函数\变量;object
中均为static函数变量,为单例模式使用.
若object
还与类同名,则为伴生对象,类似于友元,还可以访问私有成员.- 声明一个object, 一个匿名类就会被创建。
使用方法:
- 成员函数,变量: new一个对象出来调用;
- 静态函数,变量,或者想使用单例模式: 在同文件中写一个object,然后通过object来定义静态成员,并写使用接口. 如果需要访问私有成员,则这个
object
需要和class同名.
总结:
class
: 实例成员的集合object
: 静态成员的集合- 单例: private构造函数,然后创建
object
. 因为需要访问构造函数,所以其实真正能用的单例对象都是同名的伴生对象. 非同名的object只能称为未关联class的object,可以作为main程序调用. - 访问私有成员: 创建同名
object
(伴生对象)
scala类修饰符
1 | //1.使用var声明field,则该field将同时拥有getter和setter |
但是注意对于Case Class,则稍有不同!Case Class对于通过Primary Constructor声明的字段自动添加val修饰,使之变为只读的。
主构造函数:Primary Constructor
scala的主构造函数指的是在定义Class时声明的那个函数. 函数的参数就是类的参数,函数体就是类定义中可执行的部分.
(感觉连类也像是一个函数)
1 | class MongoClient(var host: String, var port: Int) { |
Trait 特征
带有方法实现\字段的接口,没有参数 (使用的extends关键字,因此更像是抽象类)
“堆栈化”(叠加)继承特性: 从左到右入栈,从右到左出栈解析;忽略已经出现的方法.(右侧优先深度优先)
- 特征构造顺序(与序列化相反)Trait与接口的区别在于,Trait可以直接添加到对象上,而不用在
1
2
3
4父类构造器
特征构造器(从右到左)
每个特征当中,父特征先被构造
子类构造器class
中声明. - 示例如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
trait Debugger {
def log(message: String) {
println(message)
}
}
class Worker {
def work() {
println("working innocently")
}
}
object TestLogger extends App {
val worker = new Worker() with Debugger // 这里直接附加trait
worker.work()
worker.log("log here")
}
Case Class
主构造函数的所有参数会被自动限定为val,也就意味着这个字段是外部可读的。Case Class
可以方便得用于DTO(或者叫V0,数据传输对象)的创建,当你希望设计一个类只是作为数据载体的时候.
scala编译器会为case class自动生成一个伴生对象,为class生成4个常用方法:
1 | equals |
为伴生对象object生成2个常用方法:
1 | apply |
上述行为的实现,从编译后的代码看,似乎只写了这些:
1 | with scala.Product with scala.Serializable |
可能这些方法就在Product和Serializable里? 点进去看是空的.
- sealed关键字case class的companion object是隐式自动生成的
1
2
3
4
5
6
7//sealed关键字声明其他trait都不能再继承当前的trait
//除非这个类与声明的这个trait在同一个class文件里!
sealed trait QueryOption
case object NoOption extends QueryOption
case class Sort(sorting: DBObject, anotherOption: QueryOption) extends QueryOption
case class Skip(number: Int, anotherOption: QueryOption) extends QueryOption
case class Limit(limit: Int, anotherOption: QueryOption) extends QueryOption1
2
3
4
5
6
7
8
9
10case class Person(firstName:String, lastName: String)
//注意:case class的companion object是隐式自动生成的!下面的代码并不是手动编写的。
object Person {
def apply(firstName:String, lastName:String) = {
new Person(firstName, lastName)
}
def unapply(p:Person): Option[(String, String)] =
Some((p.firstName, p.lastName))
}
unapply
Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。
泛型之 Invariant 与 Covariance/Contravariance
默认情况下,scala的泛型是Invariant,也就是强类型,不允许自动上下转型.
1 | // +A 表示自动允许向上转型 |
Null/None/Nothing/Nil
null
是Null
的唯一对象。Null
是所有引用类型的子类,Any
<-AnyRef
<-Null
;Nothing
是所有类型的子类.返回值是Unit
表示没有返回值,返回值是Nothing
表示不但没有返回值,而且还不返回,要想离开这个函数只能抛异常;1
如果一个函数可以返回Int,也可以抛异常,则这个函数的返回类型写Int即可. 因为Nothing也是Int的子类, 返回类型可以接受向上转型.
None
是Option
的子类.Option
<-Some
/None
;Nil
是所有List[T]的子类,表示空列表. (List的声明为List[+A],接受向上转型)
type 关键字
scala里的类型,除了在定义class,trait,object时会产生类型,还可以通过type关键字来声明类型。
1 | def typeOf[T](v: T): String = v match { |
<: 与 >:
类型上确界和类型下确界
1 | // T <: Animal的意思是:T必须是Animal的子类(<=) |
Mutable 和 Immutable
Mutable: 被修改时返回原对象引用
Immutable: 被修改时返回新对象的引用