Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。
Scala 运行在Java虚拟机上,并兼容现有的Java程序。
Scala 源代码被编译成Java字节码,所以它可以运行于JVM之上,并可以调用现有的Java类库。
scala特性
- 面向对象
Scala是一种纯面向对象的语言,每个值都是对象。对象的数据类型以及行为由类和特质描述。
类抽象机制的扩展有两种途径:一种途径是子类继承,另一种途径是灵活的混入特制。这两种途径能避免多重继承的种种问题。 - 函数式编程
Scala也是一种函数式语言,其函数也能当成值来使用。 - 静态类型
- 扩展性
- 并发性
scala访问修饰符
- private
class Outer{
class Inner{
private def f(){println("f")}
class InnerMost{
f() // 正确
}
}
(new Inner).f() //错误
}
(new Inner).f( ) 访问不合法是因为 f 在 Inner 中被声明为 private,而访问不在类 Inner 之内。
但在 InnerMost 里访问 f 就没有问题的,因为这个访问包含在 Inner 类之内。
Java中允许这两种访问,因为它允许外部类访问内部类的私有成员。
- protected
package p{
class Super{
protected def f() {println("f")}
}
class Sub extends Super{
f()
}
class Other{
(new Super).f() //错误
}
}
上例中,Sub 类对 f 的访问没有问题,因为 f 在 Super 中被声明为 protected,而 Sub 是 Super 的子类。相反,Other 对 f 的访问不被允许,因为 other 没有继承自 Super。而后者在 java 里同样被认可,因为 Other 与 Sub 在同一包里。
- 作用域保护
package bobsrocckets{
package navigation{
private[bobsrockets] class Navigator{
protected[navigation] def useStarChart(){}
class LegOfJourney{
private[Navigator] val distance = 100
}
private[this] var speed = 200
}
}
package launch{
import navigation._
object Vehicle{
private[launch] val guide = new Navigator
}
}
}
上述例子中,类Navigator被标记为private[bobsrockets]就是说这个类对包含在bobsrockets包里的所有的类和对象可见。
比如说,从Vehicle对象里对Navigator的访问是被允许的,因为对象Vehicle包含在包launch中,而launch包在bobsrockets中,相反,所有在包bobsrockets之外的代码都不能访问类Navigator。
scala循环判断
#1. for循环
for( var x <- Range ){
statement(s)
}
#Range 可以是一个数字区间表示 i to j ,或者 i until j
var a = 0
var b = 0
// for 循环嵌套
for( a <- 1 to 3; b <- 1 to 3){
println( "Value of a: " + a )
println( "Value of b: " + b )
}
for( var x <- List ){
statement(s);
}
var a = 0;
val numList = List(1,2,3,4,5,6,7,8,9,10);
// for 循环过滤
for( a <- numList if a != 3; if a < 8 ){
println( "Value of a: " + a )
}
var a = 0;
val numList = List(1,2,3,4,5,6,7,8,9,10);
// for 循环保存值 返回一个List
var retVal = for{ a <- numList if a != 3; if a < 8}yield a
#2. while循环
while(condition)
{
statement(s)
}
#3. do...while循环
do {
statement(s);
} while( condition )
4. 判断
if(布尔表达式 1){
// 如果布尔表达式 1 为 true 则执行该语句块
}else if(布尔表达式 2){
// 如果布尔表达式 2 为 true 则执行该语句块
}else if(布尔表达式 3){
// 如果布尔表达式 3 为 true 则执行该语句块
}else {
// 如果以上条件都为 false 执行该语句块
}
scala方法与函数
Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。
Scala 中的方法跟 Java 的类似,方法是组成类的一部分。
Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。
Scala 中使用 val 语句可以定义函数,def 语句定义方法。
def m(x: Int) = x + 3
val f = (x: Int) => x + 3
方法和函数的区别
- 函数可作为一个参数传入到方法中,而方法不行。
- 在Scala中无法直接操作方法,如果要操作方法,必须先将其转换成函数。
val f1 = m _ #方法转函数
- 函数必须要有参数列表,而方法可以没有参数列表
递归函数意味着函数可以调用它本身。
- 传名参数与传值参数
Scala的解释器在解析函数参数(function arguments)时有两种方式:
传值调用(call-by-value):先计算参数表达式的值,再应用到函数内部;
传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部
在进入函数内部前,传值调用方式就已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。变量名和变量类型使用 => 符号来设置传名调用。
- 匿名函数
val f = (a: Int) => a + 1 #接受一个参数的匿名函数
f(2) #调用匿名函数
val f = () => println("haha") #没有参数的匿名函数
f() #调用匿名函数
- 偏应用函数
Scala 偏应用函数是一种表达式,你不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。对给定的输入参数类型,偏函数只能接受该类型的某些特定的值。一个定义为(Int) => String 的偏函数可能不能接受所有Int值为输入。
def main(date: Date, message: String) = {}
val f = main(new Date, _: String)
f("message")
- 函数柯里化
柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。
def add(x:Int,y:Int)=x+y
def add(x: Int)(y: Int) = x + y
- 闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
闭包通常来讲可以简单的认为是可以访问一个函数里面局部变量的另外一个函数。
var factor = 3
val multiplier = (i:Int) => i * factor
scala字符串
在 Scala 中,字符串的类型实际上是 Java String,它本身没有 String 类。(java.lang.String)
在 Scala 中,String 是一个不可变的对象,所以该对象不可被修改。这就意味着你如果修改字符串就会产生一个新的字符串对象。
val str = "hello world"
str.length()
str1.concat(str2)
str1 + str2
scala数组
特性:数组是用来存储固定大小的同类型元素,数组中某个指定的元素是通过索引来访问的。数组是有序的,可以包含重复项,并且可变。
val myArray = Array.empty[Int] #创建空数组
val myArray = new Array[Int](3)#创建数组
myArray(0) = 1#赋值
val myArray = Array(1, 2, 3)#创建数组
val myArray = Array.range(1, 4, 2)#创建数组
for(x <- myArray) println(x)#遍历数组
val myMatrix = Array.ofDim[Int](3, 3)#创建多维数组
Array.concat(array1, array2) #合并数组
scala集合
Scala 集合分为可变的和不可变的集合。
- List(列表)
特性:所有元素类型相同,链接表结构,元素以线性方式存储,可以存放重复对象。列表是有序的,可以包含重复项,不可变。
val site = List("Runoob", "Google", "Baidu")
val site2 = "Runoob" :: "Google" :: "Baidu" :: Nil
site.head
site.tail
site.isEmpty
site ::: site2 #合并
site.:::(site2) #合并
List.concat(site, site2) #合并
List.fill(3)("Runoob") #List("Runoob", "Runoob", "Runoob") 重复 Runoob 3次
List.tabulate(3)(n => n * n) #List(0, 1, 4) 通过给定的函数来创建列表,起始值为 0
site.reverse
"Facebook" +: site #返回一个新列表,元素追加在开头,List("Facebook", "Runoob", "Google", "Baidu")
site :+ "Facebook" #返回一个新列表,元素追加在末尾,List("Runoob", "Google", "Baidu", "Facebook")
site.length #3
- Set(集合)
集合中的对象不按特定的方式排序,并且没有重复对象。集合无序且不可包含重复项。
val set = Set(1, 2, 3)
set.exists(_ % 2 == 0) #true
set.drop(2) #Set(3)
set.head
set.tail
set.isEmpty
set ++ set2 #连接两个set
set.++(set2)
set.max
set.min
set.&(set2) #求交集
set.intersect(set2) #求交集
set + 5 #添加元素
set + (4, 5) #添加多个元素
set.size #3
#可变Set
import scala.collection.mutable.Set
val mutableSet = Set(4, 5, 6)
mutableSet.add(7) #添加元素,返回true或者false
mutableSet.remove(7) #移除某个元素,返回true或者false
mutableSet += 7 #添加元素
mutableSet -= 7 #移除某个元素
- Map(映射)
是一种可迭代的键值对(key/value)结构,键都是唯一的。
val map = Map("one" -> 1, "two" -> 2)
map.keys #Set("one", "two")
map.values #MapLike(1, 2)
map.isEmpty
map ++ map2 #合并,若key重复,就覆盖其值
map.++(map2) #合并
map.contains("one")
map + ("three" -> 3, "four" -> 4)
map - ("one", "two")
map.get("one") #Some(1)
- tuple(元组)
可以包含不同类型的元素,目前 Scala 支持的元组最大长度为 22。
val tuple = (1, 3.14, 'a', "one")
val tuple2 = new Tuple4(1, 3.14, 'a', "one") #创建元组
tuple._1 #访问第一个元素,返回其值1
tuple.productIterator.foreach(println) #遍历元组
tuple.productArity #返回元组中元素的个数
tuple.productElement(0) #返回该索引下的元素值1,Any类型。
- Option(选项)
Scala Option(选项)类型用来表示一个值是可选的(有值或无值)。 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。
val option: Option[Int] = Some(5)
option.get #返回其值5,如没有值,返回None
option.getOrElse(10) #返回其值5,如没有值,返回10,默认值
option.isEmpty
def show(x: Option[String]) = x match {
case Some(s) => s
case None => "?"
}
- Iterator(迭代器)
Scala Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法。
val it = Iterator("Baidu", "Google", "Runoob", "Taobao")
while (it.hasNext){
println(it.next())
}
it.max
it.min
it.size #或者it.length
scala模式匹配
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
case _ => "many"
}
println(matchTest("two"))
scala异常处理
#抛出异常
throw new IllegalArgumentException
#捕获异常
try {
//
} catch {
case e: IOException =>
println("IO Exception")
} finally {
println("Exiting finally...")
}
scala文件I/O
#读取屏幕输入内容
import scala.io._
val line = StdIn.readLine()
#读取文件内容
import scala.io.Source
Source.fromFile("test.txt" ).foreach{
print
}
#写数据到文件
import java.io._
val writer = new PrintWriter(new File("test.txt" ))
writer.write("scala 教程")
writer.close()