Scala基础语法

来源:互联网 发布:linux文件强制锁 编辑:程序博客网 时间:2024/06/14 20:35

Scala学习教程

1.Scala概述

运行在JVM上的纯面向对象和函数式编程语言,能够兼容任何Java APIKafkaSpark均由Scala编写

 

Scala特性:

1)面向对象编程

类的抽象机制包括子类继承,混入机制

2)函数式编程

函数可作为值使用,定义匿名函数,支持高阶函数,允许嵌套多层函数,并支持柯里化,除此之外case模式匹配

3)静态类型

包括泛型类,协变和逆变,标注,类型参数的上下限约束,把类别和抽象类型作为对象成员,复合类型,引用自己时显示指定类型,视图,多态方法

4)扩展性

5)并发性

Akka作为异步并发模型Actor的实现

 

2.Scala基本语法

1)区分大小写

2)类名驼峰命名法

3)方法名首字母小写

4)文件名与对象名称匹配

 

Ø Scala的保留关键字

 

Ø Scala中导包

import java.awt._  // 引入包内所有成员

import java.awt.{Color, Font}//允许使用awt包中的ColorFont

import java.util.{HashMap=>JavaHashMap} //将Java中的HashMap重命名

import java.util.{HashMap=>_}//隐藏java.util.HashMap,避免命名冲突

import java.util.{HashMap => _, _} // 引入了util包的所有成员,但是HashMap被隐藏了

Ø Scala基本数据类型

 

1)Unit:等价于Void

2)Nothing:任意类型的子类型

3)Any:任何类型的父类

4)AnyRef:所有引用类(reference class)的父类

 

多行字符串用三个双引号作为分隔符

val foo = """

www.runoob.com

www.w3cschool.cc

www.runnoob.com"""

Null类型的对象是null,是每个引用类的(继承于AnyRef类的)子类

 

Ø Scala的变量和常量

var temp:String =”Foo”  //变量定义

val temp:String=”Value”//常量定义

var myVar = 10;//定义变量,必须有初始值

val myVal = "Hello, Scala!";//定义常量,必须有初始值

Ø Scala访问修饰符

Private:带有此标记的成员仅在包含了成员定义的类或对象内部可见,同样的规则还适用内部类

Protected:允许子类访问

Public:任何地方都能访问

作用域保护:private[x]protected[x]仅允许该x(包或者类)中访问该成员

 

Ø Scala中断循环

val loop=new Breaks

loop.breakable{

for(...){//foreach

If(...){

loop.break//跳出循环

}

}

}

 

Ø Scala函数

def functionName ([参数列表]) : [return type]//函数定义,如果不写函数体,则认为是抽象方法,包含此方法的类型则为Abstract Class

1)Scala函数调用

包括传名调用(将未计算的参数表达式直接应用到函数内部)和传值调用(先计算参数表达式的值再应用到函数内部)

 

注意Scala传名调用需要:

object Test {

   def main(args: Array[String]) {

        delayed(time());

   }

   def time() = {

      println("获取时间,单位为纳秒")

      System.nanoTime

   }

   def delayed( t: => Long ) = {//通过=>声明允许传名调用

      println("在 delayed 方法内")

      println("参数: " + t)

      t

   }}

2)Scala函数可变形参

object Test {

   def main(args: Array[String]) {

        printStrings("Runoob", "Scala", "Python");

   }

   def printStrings( args:String* ) = {//通过*声明有多个String类型的形参

      var i : Int = 0;

      for( arg <- args ){

         println("Arg value[" + i + "] = " + arg );

         i = i + 1;

      }

   }}

3)Scala函数形参指定默认值

object Test {

   def main(args: Array[String]) {

        println( "返回值 : " + addInt() );

   }

   def addInt( a:Int=5, b:Int=7 ) : Int = {//形参a,b默认值为5,7

      var sum:Int = 0

      sum = a + b

      return sum

   }}

 

4)Scala函数嵌套,基于函数式编程思想,允许任意地方定义函数

 def factorial(i: Int): Int = {

      def fact(i: Int, accumulator: Int): Int = {//factorial嵌套fact

         if (<= 1)

            accumulator

         else

            fact(- 1, i * accumulator)

      }

      fact(i, 1)

   }

5)Scala偏应用函数
val logWithDateBound = log(date, _ : String)//第二个参数为缺省值

 logWithDateBound("message1" )//只需要指定第二个参数

6)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 );

   }}

7)函数递归调用

object Test {

   def main(args: Array[String]) {

      for (<- 1 to 10)

         println(+ " 的阶乘为: = " + factorial(i) )

   }

   def factorial(n: BigInt): BigInt = {  

      if (<= 1)

         1  

      else    

      n * factorial(- 1)

   }}

8)Scala高阶函数

object Test {

   def main(args: Array[String]) {

      println( apply( layout, 10) )

 

   }

   // 函数 f 和 值 v 作为参数,而函数 f 又调用了参数 v

   def apply(f: Int => String, v: Int) = f(v)//高阶函数

   def layout[A](x: A) = "[" + x.toString() + "]"//待传入函数

   }

所谓的高阶函数即允许使用其他函数作为参数

9)Scala匿名函数

var mul = (x: Int, y: Int) => x*y//定义了匿名函数mul

println(mul(3, 4))

10)Scala函数柯里化

def add(x:Int)(y:Int) = x + y //函数柯里化

add(1)(2)

Ø Scala闭包函数

var factor = 3  

val multiplier = (i:Int) => i * factor  

即函数multiplier捕获到自由变量factor过程 

 

Ø Scala字符串

1)创建字符串 val str=”caiqi” //str不可变

2)可变字符串 var strBuilder=new StringBuilder//可变字符串

3)字符串长度 val len=str.length() 

 

Ø Scala数组

var myList = Array(1.9, 2.9, 3.4, 3.5) //定义数组

遍历数组的两种方式:

1)foreach方式

for(i<-myList){

Println(i)

}

2)索引方式

for(i<-0 to array.length-1){

println(array(i))

}

var myMatrix = ofDim[Int](3,3)  //定义二维数组

for (<- 0 to 2) {

         for ( j <- 0 to 2) {

            myMatrix(i)(j) = j;

         }

      }

 var myList3 =  concat( myList1, myList2) //数组合并

 var myList1 = range(10, 20, 2)//创建步长为2的范围数组{10,12,14,16,18}

Ø Scala Collection

1)Scala List(列表)

// 字符串列表

val site: List[String] = List("Runoob", "Google", "Baidu")

// 整型列表

val nums: List[Int] = List(1, 2, 3, 4)

// 空列表

val empty: List[Nothing] = List()

// 二维列表

val dim: List[List[Int]] =

   List(

      List(1, 0, 0),

      List(`0, 1, 0),

      List(0, 0, 1)

   )

list1:::list2 等价于 list1.concat(list2)  //连接列表

List.fill(3)(caiqi)  //创建一个有3caiqi元素的列表

2)Scala Set(集合)

默认是不可变集合

val set = Set(1,2,3)

可变集合 scala.collection.mutable.Set

val mutableSet = Set(1,2,3)

mutableSet.add(4)  //可变集合

set1++set2 //合并且去重集合

set1.&(set2)或者set1.intersect(set2) //set1set2的交集

3)Scala MapHash表)

默认是不可变映射表,可变映射表 scala.collection.mutable.Map

val colors = Map("red" -> "#FF0000", "azure" -> "#F0FFFF")

colors+=(green->xinghai)

colors1++colors2 合并且去重

val sites = Map("runoob" -> "http://www.runoob.com",

                       "baidu" -> "http://www.baidu.com",

                       "taobao" -> "http://www.taobao.com")

 

      sites.keys.foreach{ i =>  

                           print( "Key = " + i )

                           println(" Value = " + sites(i) )}

   }}

 

Ø Scala元祖(每个元素类型可能不一样)

val t = (1, 3.14, "Fred")  //定义元祖

t.productIterator.foreach{ i =>println("Value = " + i )}//迭代元祖

 

Ø Scala Option 如果值存在, Option[T] 就是一个 Some[T] ,如果不存在, Option[T] 就是对象 None 

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

 def show(x: Option[String]) = x match {// 模式匹配

      case Some(s) => s

      case None => "?"

   }

      val a:Option[Int] = Some(5)

      val b:Option[Int] = None 

      println("a.getOrElse(0): " + a.getOrElse(0) )//op.getOrElse(default),即若op有值则返回,若op没值则返回default

      println("b.getOrElse(10): " + b.getOrElse(10) )

 

Ø Scala Iterator(迭代器)

object Test {

   def main(args: Array[String]) {

      val it = Iterator("Baidu", "Google", "Runoob", "Taobao")

      while (it.hasNext){//遍历

         println(it.next())

      }

   }}

it.max最大值,it.min最小值

Ø Scala类与对象

类是抽象的,对象是具体的

class Point(xc: Int, yc: Int) {//xy可以理解为Point类的属性

   var x: Int = xc

   var y: Int = yc

 

   def move(dx: Int, dy: Int) {//move可以理解为Point类的行为

      x = x + dx

      y = y + dy

      println ("x 的坐标点: " + x);

      println ("y 的坐标点: " + y);

   }}

object Test {

   def main(args: Array[String]) {

      val pt = new Point(10, 20);//构造Point对象pt

 

      // 移到一个新的位置

      pt.move(10, 10);

   }}

类的继承:

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 ("x 的坐标点 : " + x);

      println ("y 的坐标点 : " + y);

   }}

class Location(override val xc: Int, override val yc: Int,

   val zc :Int) extends Point(xc, yc){

//Location继承于Point,当参数相同时需加override字段,类初始化顺序

首先是父类的构造方法,然后初始化本类的属性

   var z: Int = zc

 

   def move(dx: Int, dy: Int, dz: Int) {

      x = x + dx

      y = y + dy

      z = z + dz

      println ("x 的坐标点 : " + x);

      println ("y 的坐标点 : " + y);

      println ("z 的坐标点 : " + z);

   }}

object Test {

   def main(args: Array[String]) {

      val loc = new Location(10, 20, 15);

 

      // 移到一个新的位置

      loc.move(10, 10, 5);

   }}

 

Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对象,它和类的区别是,object对象不能带参数,这个object对象称为伴生对象,类和其伴生对象可以互相访问其私有成员

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")  

    }}

当Marker(“red”)第一次调用时,首先会隐式调用伴生对象中的apply方法,初始化伴生对象即初始化markers,由于之前初始化过new Marker("red"),单例模式下不会再次初始化,而会直接得到上次初始化的引用,Maker getMarker blue同理

Ø Scala Trait特征

trait Equal {

  def isEqual(x: Any): Boolean

  def isNotEqual(x: Any): Boolean = !isEqual(x)}

Trait特征修饰的接口中可以定义属性和方法的实现,支持多继承,子类需要实现trait中未实现的接口方法,子类的构造顺序:

构造器的执行顺序:

· 调用超类的构造器;

· 特征构造器在超类构造器之后、类构造器之前执行;

· 特征由左到右被构造;

· 每个特征当中,父特征先被构造;

· 如果多个特征共有一个父特征,父特征不会被重复构造

· 所有特征被构造完毕,子类被构造。

 

Ø Scala模式匹配(match case类似于switch case)

object Test {

   def main(args: Array[String]) {

    val alice = new Person("Alice", 25)

val bob = new Person("Bob", 32)

    val charlie = new Person("Charlie", 32)

   

    for (person <- List(alice, bob, charlie)) {

     person match {

            case Person("Alice", 25) => println("Hi Alice!")

            case Person("Bob", 32) => println("Hi Bob!")

            case Person(name, age) =>

               println("Age: " + age + " year, name: " + name + "?")

         }

      }

   }

   // 样例类

   case class Person(name: String, age: Int)

Ø Scala异常处理

object Test {

   def main(args: Array[String]) {

      try {

         val f = new FileReader("input.txt")

      } catch {

         case ex: FileNotFoundException =>{ //利用模式匹配处理异常

            println("Missing file exception")

         }

         case ex: IOException => {

            println("IO Exception")

         }

      }

   }}

Ø Scala提取器(Extractor)

object Test {

   def main(args: Array[String]) {

      

      println ("Apply 方法 : " + apply("Zara", "gmail.com"));

      println ("Unapply 方法 : " + unapply("Zara@gmail.com"));

      println ("Unapply 方法 : " + unapply("Zara Ali"));

 

   }

   // 注入方法 (可选)

   def apply(user: String, domain: String) = {

      user +"@"+ domain//不需要new便能构造对象

   }

 

   // 提取方法(必选)

   def unapply(str: String): Option[(String, String)] = {

      val parts = str split "@"

      if (parts.length == 2){

         Some(parts(0), parts(1)) //从对象中提取值并构造新的对象

      }else{

         None

      }

   }}

Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。

 

Ø Scala文件I/O

import java.io._

object Test {

   def main(args: Array[String]) {

      val writer = new PrintWriter(new File("test.txt" ))//往文件写入

 

      writer.write("菜鸟教程")

      writer.close()

   }}

object Test {

   def main(args: Array[String]) {

      print("请输入菜鸟教程官网 : " )

      val line = Console.readLine//从控制台读数据

      println("谢谢,你输入的是: " + line)

   }}

object Test {

   def main(args: Array[String]) {

      println("文件内容为:" )

      Source.fromFile("test.txt" ).foreach{ //从文件读

         print 

      }

   }}

 

原创粉丝点击