scala之语法基础

author: mys

since: 2020-08-13

一、 简介:

Scala 也是一种函数式语言,函数是 Scala 语言的核心。

二、基础语法:

scala hello world :

object HelloWorld {
  def main(args: Array[String]) :Unit={
    println("Hello, world!") // 输出 Hello World
  }
}

object关键字定义了一个单例对象

1、数据类型:

与java相似,少部分有区别。Any是其他类的超类,Unit等同于Java的void。

数据类型描述
Byte8位有符号补码整数。数值区间为 -128 到 127
Short16位有符号补码整数。数值区间为 -32768 到 32767
Int32位有符号补码整数。数值区间为 -2147483648 到 2147483647
Long64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
Float32 位, IEEE 754 标准的单精度浮点数
Double64 位 IEEE 754 标准的双精度浮点数
Char16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF
String字符序列
Booleantrue或false
Unit表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
Nullnull 或空引用
NothingNothing类型在Scala的类层级的最底端;它是任何其他类型的子类型。
AnyAny是所有其他类的超类
AnyRefAnyRef类是Scala里所有引用类(reference class)的基类
2、变量声明:

在 Scala 中,使用关键词 “var” 声明变量,使用关键词 “val” 声明常量。

声明语法为:

var VariableName : DataType [=  Initial Value]val VariableName : DataType [=  Initial Value]

例如:
// 声明变量 myVar,可以修改
var myVar : String = "Foo"
// 声明常量 myVal,修改编译报错
val myVal : String = "Foo"

var a:Int = 0
var b:Long = 0L
var c:Float = 0.0f
var d:String = "test"
......
3、访问权限控制:

Scala 访问修饰符基本和Java的一样,分别有:private,protected,public

如果没有指定访问修饰符,默认情况下,Scala 对象的访问级别都是 public。

各个访问权限与Java稍有不同:

(1) private 限定符比 Java 更严格,在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员;

(2)Protected限定符比 Java 更严格,它只允许保护成员在定义了该成员的的类的子类中被访问;

4、方法与函数:

Scala 有方法与函数,二者在语义上的区别很小。

Scala 中的方法跟 Java 的类似,方法是组成类的一部分。

Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。

Scala 中使用 val 语句可以定义函数,def 语句定义方法。

函数是可以作为参数传递, 方法可以转换成函数。

// 声明一个方法
def functionName ([参数列表]) : [return type]

// 定义一个方法
def functionName ([参数列表]) : [return type] = {
   function body
   return [expr]
}

// 定义一个函数
val methodName = ([参数列表]) => [函数体]


e.g.

import java.util

object Opp{

  // 定义一个方法,两数相加
  def addInt( a:Int, b:Int ) :Int = {
    var sum:Int = 0
    sum = a + b
    return sum
  }

  // 定义函数 addIntMet,两数相加
  val addIntMet = (x:Int,y:Int) => x + y

  //定义函数multiIntMet,两数相乘
  val multiIntMet = (m:Int,n:Int) => m * n

  // 函数可以作为参数传递
  def methodPara(a :Int, b :Int, f:(Int, Int) => Int) = {
    f(a, b)
  }

  // 定义返回Unit(相当于 void)
  def myprint( a:Int) : Unit  = {
    println("The value is:" + a);
  }

  def main(args: Array[String]) {

    myprint(addInt(1, 2));
    val r1 = multiIntMet(addIntMet(1,2), 4)
    myprint(r1)

    // 方法addInt不是对象,不能赋值给变量
    //var func = addInt
    // 函数addIntMet最为对象可以赋值给变量
    var meth = addIntM

    //在方法名后加上“ _ ” ,可以将方法转换成函数
    var func = addInt _

    // 函数作为参数传递
    var retParaMeth = methodPara(1, 2, addIntMet)
    println(retParaMeth)

    /*
     * 这里自动将方法addInt,转换为了函数
     * 等价于:
     * var retParaFunc = methodPara(2, 3, addInt _)
     */
    var retParaFunc = methodPara(2, 3, addInt)
    println(retParaFunc)
    
    // 匿名函数的应用
    var myList:List[Int] = List()
    myList = myList :+ 1
    myList = myList :+ 2
    myList = myList :+ 3
    // 传递匿名函数修改list数据
    myList = myList.map(elem =>elem*2)
    for(elem <- myList){		// 遍历list
      println(elem)
    }

  }
}
5、数组、collection、iterator:
5.1 数组:
var z:Array[String] = new Array[String](3)var z = new Array[String](3)var z = Array("Runoob", "Baidu", "Google")

数组的遍历:

object Test {
   def main(args: Array[String]) {
      var myList = Array(1.9, 2.9, 3.4, 3.5)
      
      // 输出所有数组元素
      for ( x <- myList ) {
         println( x )
      }

      // 计算数组所有元素的总和
      var total = 0.0;
      for ( i <- 0 to (myList.length - 1)) {
         total += myList(i);
      }
      println("总和为 " + total);

      // 查找数组中的最大元素
      var max = myList(0);
      for ( i <- 1 to (myList.length - 1) ) {
         if (myList(i) > max) max = myList(i);
      }
      println("最大值为 " + max);
    
   }
}
5.2 collection 与 iterator:

scala中的集合:

序号集合及描述
1Scala List(列表)List的特征是其元素以线性方式存储,集合中可以存放重复对象。参考 API文档
2Scala Set(集合)Set是最简单的一种集合。集合中的对象不按特定的方式排序,并且没有重复对象。参考 API文档
3Scala Map(映射)Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。参考 API文档
4Scala 元组元组是不同类型的值的集合
5Scala OptionOption[T] 表示有可能包含值的容器,也可能不包含值。
6Scala Iterator(迭代器)迭代器不是一个容器,更确切的说是逐一访问容器内元素的方法。
var list1:List[String] = List("e", "f")
list1 = "a" +: list1    // 向队首添加元素
list1 = list1 :+ "g"    // 向队尾添加元素
    
for(str <- list1){		// 遍历list
   println(str)
}


var myMap:Map[String, Int] = Map()
// 添加元素
myMap += ("a"->1)	
// 遍历map
for(elem <- myMap){
  println("key is :" + elem._1+" ,value is :"+elem._2)
}

// 迭代
var it = myMap.iterator
while(it.hasNext){
	var elem =  it.next()
    println("key is :" + elem._1+" ,value is :"+elem._2)
}

三、类、对象、继承:

1、Scala中类的概念:

类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是创建包含特定方法和变量的实例对象的软件模板。

scala 中的类:

class Person(val pname: String, val pgender: String,
                      val page: Int, val paddress: String){
  var name:String = pname

  var gender:String = pgender

  var age:Int = page

  var address :String = paddress

  def printInfo()={
    println("my name is "+name +", my gender is "+gender +", my age is "+age
    +", my adress is "+address)
  };

}

Scala中的类不声明为public,一个Scala源文件中可以有多个类。

Scala 的类定义可以有参数,称为类参数,如上面的 pname,pgender,page, paddress,类参数在整个类中都可以访问。

我们可以使用 new 来实例化类,并访问类中的方法和变量。

2、单例对象:

在 Scala 中,是没有 static 关键字,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object。

Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对象,它和类的区别是,object对象不能带参数。

当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象:companion object。你必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类:companion class。类和它的伴生对象可以互相访问其私有成员。

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
   }
}

object Test {
   def main(args: Array[String]) {
      val point = new Point(10, 20)
      printPoint

      def printPoint{
         println ("x 的坐标点 : " + point.x);
         println ("y 的坐标点 : " + point.y);
      }
   }
}

伴生对象:

// 私有构造方法
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")  
    }
}
3、继承:

3.1 单继承:

Scala继承一个基类跟Java很相似, 但我们需要注意以下几点:

  • 1、重写一个非抽象方法必须使用override修饰符。
  • 2、只有主构造函数才可以往基类的构造函数里写参数。
  • 3、在子类中重写超类的抽象方法时,你不需要使用override关键字。
package net.zhongfu.sparktest

// Person 超类
class Person(val pname: String, val pgender: String,
                      val page: Int, val paddress: String){
  var name:String = pname

  var gender:String = pgender

  var age:Int = page

  var address :String = paddress

  def printInfo()={
    println("my name is "+name +", my gender is "+gender +", my age is "+age
    +", my adress is "+address)
  };

}

// student继承
class Student(override val pname:String , override val pgender: String,
              override val page :Int, override val paddress :String, val pfather:String, val pmother:String)
  extends Person(pname, pgender, page, paddress){

  var father:String = pfather
  var mother:String = pmother

  override def printInfo(): Unit = {
    println("my name is "+name +", my gender is "+gender +", my age is "+age
        +", my adress is "+address+", my father is "+father +", my mother is "+mother)

  }
}

object XiaoMing{

  def main(args: Array[String])={
    var xiaoming:Student = new Student("xiaoming", "male", 12, "shandong", "zhangsan", "cuihua");
    xiaoming.printInfo();
  }
}

Scala 使用 extends 关键字来继承一个类。实例中 Location 类继承了 Point 类。Point 称为父类(基类),Location 称为子类。

override val xc 为重写了父类的字段。

继承会继承父类的所有属性和方法,Scala 只允许继承一个父类。

Scala重写一个非抽象方法,必须用override修饰符。

3.2 多重继承的实现:

在java中可以通过interface实现多重继承,在Scala中可以通过特征(trait)实现多重继承,不过与java不同的是,它可以定义自己的属性和实现方法体,Scala Trait(特征)更像 Java 的抽象类。

在Scala中也是一般只能继承一个父类,可以通过多个with进行多重继承。


// Person 超类
class Person(val pname: String, val pgender: String,
                      val page: Int, val paddress: String){
  var name:String = pname

  var gender:String = pgender

  var age:Int = page

  var address :String = paddress

  def printInfo()={
    println("my name is "+name +", my gender is "+gender +", my age is "+age
    +", my adress is "+address)
  };

}

// 特质Occupation(接口/可以多重继承的抽象类)
trait Occupation{
  // 职业工作方式
  var workingWay:String

  def myWorkWing():String;

}

// student继承
class Student(override val pname:String , override val pgender: String,
              override val page :Int, override val paddress :String,
              val pfather:String, val pmother:String) extends Person(pname, pgender, page, paddress) with Occupation{

  var father:String = pfather
  var mother:String = pmother

  override var workingWay: String = "study"

  override def printInfo(): Unit = {
    println("my name is "+name +", my gender is "+gender +", my age is "+age
        +", my adress is "+address+", my father is "+father +", my mother is "+mother
        + "," +myWorkWing())
  }

  override def myWorkWing(): String = {
      " my working way is " +workingWay
  }

}


object XiaoMing{

  def main(args: Array[String])={
    var xiaoming:Student = new Student("xiaoming", "male", 12, "shandong", "zhangsan", "cuihua");
    xiaoming.printInfo();
  }
}

四、模式匹配:

对应switch

object Test {
   def main(args: Array[String]) {
      println(matchTest(3))

   }
   def matchTest(x: Int): String = x match {
      case 1 => "one"
      case 2 => "two"
      case _ => "many"
   }
}

五、异常处理:

捕获异常:

在scala中使用try、catch、finally作异常捕捉的机制,借用了模式匹配的思想来做异常的匹配。

import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException

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")
         }
      } finally {
         println("Exiting finally...")
      }
   }
}

抛出异常:

throw new IllegalArgumentException
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值