scala笔记,主要摘自网络教程

1.scala是一种纯面向对象的语言,每个值都是对象。对象的数据类型以及行为由类和特质描述
2.类的扩展有2种机制:继承和混入机制
3.scala是一种函数式语言,其函数也能当成值来使用
4.scala使用actor作为其并发模型,actor是类似线程的实体,通过邮箱发收消息。actor可以复用线程,因此在程序中可用数百万个actor,而线程只能创建数千个
5.scala与java语法最大的区别是:scala语句末尾的分号是可选的
6.所有类名首字母大写,方法名首字母小写,程序文件名与对象名称可以不匹配,但建议保留匹配的习惯;def main(args: Array[String]),scala程序从main()方法开始处理
7.Unit表示无值,同void.Unit只有一个实例值,写成()
8.Nothing类型在scala的类层级的最低端,它是任何其它类型的子类型
9.Any是所有其它类的超类
10.AnyRef类是scala里所有引用类的基类
11.符号字面量‘<标识符>被映射成预定义类scala.Symbol的实例
如: 符号字面量 'x 是表达式 scala.Symbol("x") 的简写,符号字面量定义如下:
package scala
final case class Symbol private (name: String) {
   override def toString: String = "'" + name
}
12.多行字符串用三个双引号来表示分割符,实例如下:
val foo = """菜鸟教程
www.runoob.com
www.w3cschool.cc
www.runnoob.com
以上三个地址都能访问"""
13.var声明变量,val声明常量,修改常量时会在编译时报错
14.变量类型声明一定要有初始值,否则会报错
var VariableName : DataType [=  Initial Value]
或
val VariableName : DataType [=  Initial Value]
15.默认情况下访问级别是public
16.scala中的函数其实就是继承了trait的类对象,scala中使用val语句定义函数,def定义方法
def functionName ([参数列表]) : [return type]
17.scala在函数调用的时候,可以通过指定参数名,并且不按照顺序向函数传递参数,实例如下:
object Test {
   def main(args: Array[String]) {
        printInt(b=5, a=7);
   }
   def printInt( a:Int, b:Int ) = {
      println("Value of a : " + a );
      println("Value of b : " + b );
   }
}
18.for语法
18.1.Range风格的for循环
for( var x <- Range ){
   statement(s);
}

以上语法中,Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x 赋值。

i to j 包含j
i until j 不包含j
18.2.分号(;)风格的for循环,可以设置多个区间同时循环,即多重循环,实例:
object Test {
   def main(args: Array[String]) {
      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 );
      }
   }
}

输出结果:

Value of a: 1
Value of b: 1
Value of a: 1
Value of b: 2
Value of a: 1
Value of b: 3
Value of a: 2
Value of b: 1
Value of a: 2
Value of b: 2
Value of a: 2
Value of b: 3
Value of a: 3
Value of b: 1
Value of a: 3
Value of b: 2
Value of a: 3
Value of b: 3
18.3.for遍历集合,语法:
for( var x <- List ){
   statement(s);
}

实例:

object Test {
   def main(args: Array[String]) {
      var a = 0;
      val numList = List(1,2,3,4,5,6);

      // for 循环
      for( a <- numList ){
         println( "Value of a: " + a );
      }
   }
}
18.4.for循环过滤,语法:
for( var x <- List
      if condition1; if condition2...
   ){
   statement(s);

实例:

object Test {
   def main(args: Array[String]) {
      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 );
      }
   }
}
18.5.for循环使用yield将循环过滤的返回值用作变量存储,语法:
var retVal = for{ var x <- List
     if condition1; if condition2...
}yield x

大括号用于保存变量和条件,retVal是变量,循环中的yield会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。实例:

object Test {
   def main(args: Array[String]) {
      var a = 0;
      val numList = List(1,2,3,4,5,6,7,8,9,10);

      // for 循环
      var retVal = for{ a <- numList 
                        if a != 3; if a < 8
                      }yield a

      // 输出返回值
      for( a <- retVal){
         println( "Value of a: " + a );
      }
   }
}

执行结果:

value of a: 1
value of a: 2
value of a: 4
value of a: 5
value of a: 6
value of a: 7
19.scala允许最后一个参数是可以重复的,通过在参数的类型之后放一个星号来设置可变参数,例如:
object Test {
   def main(args: Array[String]) {
        printStrings("Runoob", "Scala", "Python");
   }
   def printStrings( args:String* ) = {
      var i : Int = 0;
      for( arg <- args ){
         println("Arg value[" + i + "] = " + arg );
         i = i + 1;
      }
   }
}

执行结果为:

Arg value[0] = Runoob
Arg value[1] = Scala
Arg value[2] = Python
20. scala偏应用函数是一种表达式,你不需要提供函数所需要的所有参数,只需要提供部分参数,或不提供所需参数,例如:
import java.util.Date

object Test {
   def main(args: Array[String]) {
      val date = new Date
      val logWithDateBound = log(date, _ : String)

      logWithDateBound("message1" )
      Thread.sleep(1000)
      logWithDateBound("message2" )
      Thread.sleep(1000)
      logWithDateBound("message3" )
   }

   def log(date: Date, message: String)  = {
     println(date + "----" + message)
   }
}

输出结果为:

Mon Dec 02 12:53:56 CST 2013----message1
Mon Dec 02 12:53:56 CST 2013----message2
Mon Dec 02 12:53:56 CST 2013----message3
21. 在scala中无法直接操作方法,如果要操作方法,必须先将其转换成函数。有两种方法转换成函数:
val f1 = m _

在方法名称m后面紧跟一个空格和下划线告诉编译器将方法m转换成函数,而不是要调用这个方法。也可以显示地告诉编译器需要将方法转换成函数:

val f1:(Int) => Int = m
22.闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。如:
var factor = 3  
val multiplier = (i:Int) => i * factor  

这里我们引入的一个自由变量factor,这个变量定义在函数外面,这样定义的函数变量multiplier成为一个“闭包”,因为它引用到函数外面的定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。完整实例:

object Test {  
   def main(args: Array[String]) {  
      println( "muliplier(1) value = " +  multiplier(1) )  
      println( "muliplier(2) value = " +  multiplier(2) )  
   }  
   var factor = 3  
   val multiplier = (i:Int) => i * factor  
}  

输出结果:

muliplier(1) value = 3  
muliplier(2) value = 6  
23.数组的定义与引用

一维数组创建

var z:Array[String] = new Array[String](3)
或
var z = new Array[String](3)
或
var z = Array("Runoob", "Baidu", "Google")

引用第i元素,注意是(),而不是[]

var myList = Array(1.9, 2.9, 3.4, 3.5)
println(myList(i))

多维数组定义

var myMatrix = ofDim[Int](3,3)

数组详细介绍

24.scala集合分为可变集合和不可变集合,对可变集合本身可以进行增删改操作,对不可变集合进行增删改操作时,会返回一个新的集合,同时保证原有集合不发生改变。

集合详细介绍

25.默认情况下scala使用不可变Map,如果你要使用可变集合,你需要显式引入import scala.collection.mutable.Map类,在scala中你可以同时使用可变与不可变Map,可变的使用mutable.Map.

初始化不可变Map:

// 空哈希表,键为字符串,值为整型
var A:Map[Char,Int] = Map()

// Map 键值对演示
val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")

添加key-value对,使用+号,如下:

A += ('I' -> 1)
A += ('J' -> 5)
A += ('K' -> 10)
A += ('L' -> 100)

Map可以使用++运算符或者Map.++()方法来连接两个Map,Map合并时会移除重复的key.

26.元组也是不可变的,但与列表不同的是元组可以包含不同类型的元素,元组的值是通过将单个的值包含在圆括号中构成的。例如:
val t = (1, 3.14, "Fred")  

以上实例在元组中定义了三个元素,对应的类型分别为[Int, Double, java.lang.String]。也可以使用以上方式来定义:

val t = new Tuple3(1, 3.14, "Fred")

元组的实际类型取决于它的元素的类型,比如 (99, "runoob") 是 Tuple2[Int, String]。 ('u', 'r', "the", 1, 4, "me") 为 Tuple6[Char, Char, String, Int, Int, String]。

27.目前scala支持的元组最大长度为22.对于更大长度可以使用集合,或者扩展元组。
28.访问元组的元素可以通过数字索引,如:
val t = (4,3,2,1)

我们可以使用t._1访问第一个元素,t._2访问第二个元素;

29.Scala Option(选项)类型用来表示一个值是可选的(有值或无值)。Option[T] 是一个类型为 T 的可选值的容器: 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 。如:
// 虽然 Scala 可以不定义变量的类型,不过为了清楚些,我还是
// 把他显示的定义上了
 
val myMap: Map[String, String] = Map("key1" -> "value")
val value1: Option[String] = myMap.get("key1")
val value2: Option[String] = myMap.get("key2")
 
println(value1) // Some("value1")
println(value2) // None
30.在类中重写一个非抽象方法必须使用override修饰符;只有主构造函数才可以往基类的构造函数里写参数;在子类中重写超类的抽象方法时,你不需要使用override关键字。
31.在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object。Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对象,它和类的区别是,object对象不能带参数。当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象:companion object。你必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类:companion class。类和它的伴生对象可以互相访问其私有成员。

单例对象实例:

/* 文件名:Marker.scala
 * author:菜鸟教程
 * url:www.runoob.com
 */

// 私有构造方法
class Marker private(val color:String) {

  println("创建" + this)
  
  override def toString(): String = "颜色标记:"+ color
  
}

// 伴生对象,与类共享名字,可以访问类的私有属性和方法
object Marker{
  
    private val markers: Map[String, Marker] = Map(
      "red" -> new Marker("red"),
      "blue" -> new Marker("blue"),
      "green" -> new Marker("green")
    )
    
    def apply(color:String) = {
      if(markers.contains(color)) markers(color) else null
    }
  
    
    def getMarker(color:String) = { 
      if(markers.contains(color)) markers(color) else null
    }
    def main(args: Array[String]) { 
        println(Marker("red"))  
        // 单例函数调用,省略了.(点)符号  
        println(Marker getMarker "blue")  
    }
}
32.trait(特征)相当于Java的接口,与接口不同的是,它还可以定义属性和方法的实现
posted @ 2018-06-20 11:21  cookiehu  阅读(287)  评论(0编辑  收藏  举报