Scala基础

来源:互联网 发布:保安腰刀淘宝店 编辑:程序博客网 时间:2024/04/23 18:07
1)scala的安装:Linux下:解压文件,将其移动至/usr/local/share下:mv scala-2.11.7 scala                   # 重命名 Scala 目录mv /download/scalapath /usr/local/share # 下载目录需要按你实际的下载路径配置环境变量:sudo vim /etc/profile在文件的末尾加入:export PATH="$PATH:/usr/local/share/scala/bin":wq!保存退出,重启终端,执行 scala 命令,测试是否安装成功。windows下:配置环境变量:变量名:SCALA_HOME变量值:scala的安装目录变量名:Path变量值:%SCALA_HOME%\bin;%SCALA_HOME%\jre\bin;(放到Path的最前面)变量名:ClassPath变量值:.;%SCALA_HOME%\bin;%SCALA_HOME%\lib\dt.jar;%SCALA_HOME%\lib\tools.jar;2)scala变量的声明:使用关键词var声明变量:var myVar : Int;var myVar : String = "Foo";使用关键词val声明常量:val myVal : String;val myVal : String = "Foo";1)变量可以修改,常量不可以修改。2)变量的类型在变量名之后等号之前声明。3)如果没有指定变量的数据类型,则可以通过变量或常量的初始值来推断其数据类型。因此,在没有指明数据类型的情况下声明变量或常量时必须要进行初始化,否则将会报错。eg:var myVar = 10;val myVal = "Hello, Scala!";4)声明多个变量:eg:val xmax, ymax = 100;  // xmax, ymax都声明为100val (myVar1, myVar2) = Pair(40, "Foo");3)scala函数的声明:函数的声明:def functionName ([参数列表]) : [return type]注意:1)如果没有写等于号和方法主体,那么声明的该方法会被隐式声明为抽象(abstract)函数。2)Scala编译器无法推断出函数参数的类型,故必须显示地标明参数的类型。函数的定义:def functionName ([参数列表]) : [return type] = {   // do something..   return [expr]}举例:def addInt(a:Int, b:Int) : Int = {var sum:Int = 0;sum = a + b;return sum;}def printMe() : Unit = {// 函数没有返回值时,函数的返回值类型设为Unit(相当于java中的void)println("Hello, Scala!")}4)scala数组的声明:要点:Scala 语言中提供的数组是用来存储固定大小的同类型元素。格式:var myArray:Array[String] = new Array[String](3);或 var myArray = new Array[String](3);或 var myArray = Array("alibaba", "Baidu", "Google");最简单的scala for语句for(i <- 1 to 10) {println("i is " + i);1 to 10表示:在1到10间(包含1和10)循环说明:本质上是一个方法,这个方法返回的是一个Range类型,它等价于:(1).to(10)注:在scala中一切皆对象,因此,这里的1就是一个对象,它有一个to方法,返回一个Range。举例:object Test {def main(args: Array[String]) {var myList = Array(1.9, 2.9, 3.4, 3.5)// 输出所有数组元素for ( x <- myList ) {println( x )}// 查找数组中的最大元素var max = myList(0);for ( i <- 0 to (myList.length - 1) ) {if (myList(i) > max) max = myList(i);}println("最大值为 " + max);}}5)scala访问修饰符:private:比Java中的private更严格;private修饰的成员(方法或变量)只能在定义它的类或对象中使用。protected:比Java中的protected更严格;protected修饰的成员只能在定义了该成员的类的子类中使用。public:如果没有指定任何的修饰符,则默认为public。public修饰的成员在任何地方都可以被访问。6)内部类:内部类中的方法或变量只能在内部类中调用。7)作用域保护:格式:修饰符[]例子:private[X] 成员名说明:1)这里的X指代某个所属的包、类或单例对象2)作用:被private[X]标记的成员,只对X范围中的类可见,对其它的类都是private。举例: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包里的所有的类和对象可见。eg:从Vehicle对象里对Navigator的访问是被允许的,因为对象Vehicle包含在包launch中,而launch包在bobsrockets中,相反,所有在包bobsrockets之外的代码都不能访问类Navigator。8)Scala中的匿名函数:格式:(x, y) => {}说明:箭头左边是参数列表,右边是函数体,参数的类型可以省略。例子:var addOne = (x:Int) => x+19)scala中的闭包:概念:闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。例子:var factor = 3;val multiplier = (i:Int) => i * factor;说明:匿名函数multiplier引用了函数外部定义的变量(factor),故这个匿名函数是一个闭包。10)scala中的类:说明:1)Scala中的类不声明为public,一个Scala源文件中可以有多个类。2)Scala中的类定义可以有参数,称为类参数。例如下面的 xc, yc,类参数在整个类中都可以访问。3)使用new关键字来来实例化类,并访问类中的方法和变量。4)Scala中没有static关键字。5)Scala中的单例对象:1>Scala中使用单例模式时,除了定义的类之外,还要定义一个同名的object对象。注意:object对象不能带参数。2>当单例对象与某个类共享同一个名称时,这个单例对象被称作是这个类的伴生对象(companion object)。注意:必须在同一个源文件里定义类和它的伴生对象。3>类被称为这个单例对象的伴生类(companion class)。注意:类和它的伴生对象可以互相访问其私有成员。定义一个类:class Point(xc: Int, 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 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")  }}执行以上代码,输出结果为:$ scalac Marker.scala $ scala Marker创建颜色标记:red创建颜色标记:blue创建颜色标记:green颜色标记:red颜色标记:blue11)Scala中的继承概念:Scala使用extends关键字来继承一个类:说明:1)重写一个非抽象方法必须使用override修饰符。2)只有主构造函数才可以往基类的构造函数里写参数。3)在子类中重写超类的抽象方法时,你不需要使用override关键字。4)继承会继承父类的所有属性和方法,Scala只允许继承一个父类。例子: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  println ("x 的坐标点 : " + x);  println ("y 的坐标点 : " + y);   }}class Location(override val xc: Int, override val yc: Int,   val zc :Int) extends Point(xc, yc){   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);   }}执行以上代码,输出结果为:$ scalac Test.scala $ scala Testx 的坐标点 : 20y 的坐标点 : 30z 的坐标点 : 20注意:Scala重写一个非抽象方法,必须用override修饰符。例子:class Person {  var name = ""  override def toString = getClass.getName + "[name=" + name + "]"}class Employee extends Person {  var salary = 0.0  override def toString = super.toString + "[salary=" + salary + "]"}object Test extends App {  val fred = new Employee  fred.name = "Fred"  fred.salary = 50000  println(fred)}执行以上代码,输出结果为:$ scalac Test.scala $ scala TestEmployee[name=Fred][salary=50000.0]12)scala中的特征(trait):概念:类似于java中的抽象类,可以定义属性和方法的实现。说明:1)特征也可以有构造器。2)特征构造顺序:构造器的执行顺序:调用超类的构造器;特征构造器在超类构造器之后、类构造器之前执行;特质由左到右被构造;每个特征当中,父特质先被构造;如果多个特征共有一个父特质,父特质不会被重复构造所有特征被构造完毕,子类被构造。13)Scala中的异常处理:抛出异常:Scala 抛出异常的方法和 Java一样,使用 throw 方法在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码里,是一系列case字句:例如:import java.io.FileReaderimport java.io.FileNotFoundExceptionimport java.io.IOExceptionobject 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") }  }   }}执行以上代码,输出结果为:$ scalac Test.scala $ scala TestMissing file exception14)Scala中的模式匹配例子:object Test {   def main(args: Array[String]) {  println(matchTest("two"))  println(matchTest("test"))  println(matchTest(1))  println(matchTest(6))   }   def matchTest(x: Any): Any = x match {  case 1 => "one"  case "two" => 2  case y: Int => "scala.Int"  case _ => "many"   }}执行以上代码,输出结果为:$ scalac Test.scala $ scala Test2manyonescala.Int说明:第一个 case 对应整型数值 1,第二个 case 对应字符串值 two,第二个 case 对应字符串值 two,第三个 case 对应类型模式,用于判断传入的值是否为整型,相比使用isInstanceOf来判断类型,使用模式匹配更好。第四个 case 表示默认的全匹配备选项,即没有找到其他匹配时的匹配项,类似 switch 中的 default。注意:1)match 对应 Java 里的 switch,但是写在选择器表达式之后。即: 选择器 match {备选项}。2)match 表达式通过以代码编写的先后次序尝试每个模式来完成计算,只要发现有一个匹配的case,剩下的case不会继续匹配。15)Scala中的正则表达式说明:1)Scala 的正则表达式继承了 Java 的语法规则,Java 则大部分使用了 Perl 语言的规则。2)Scala 通过 scala.util.matching 包种的 Regex 类来支持正则表达式。例子:import scala.util.matching.Regexobject Test {   def main(args: Array[String]) {  val pattern = "Scala".r  val str = "Scala is Scalable and cool"    println(pattern findFirstIn str)   }}执行以上代码,输出结果为:$ scalac Test.scala $ scala TestSome(Scala)说明:实例中使用 String 类的 r() 方法构造了一个Regex对象。然后使用 findFirstIn 方法找到首个匹配项。如果需要查看所有的匹配项可以使用 findAllIn 方法。你可以使用 mkString( ) 方法来连接正则表达式匹配结果的字符串,并可以使用管道(|)来设置不同的模式:例子:import scala.util.matching.Regexobject Test {   def main(args: Array[String]) {  val pattern = new Regex("(S|s)cala")  // 首字母可以是大写 S 或小写 s  val str = "Scala is scalable and cool"    println((pattern findAllIn str).mkString(","))   // 使用逗号 , 连接返回结果   }}执行以上代码,输出结果为:$ scalac Test.scala $ scala TestScala,scala如果你需要将匹配的文本替换为指定的关键词,可以使用 replaceFirstIn( ) 方法来替换第一个匹配项,使用 replaceAllIn( ) 方法替换所有匹配项,实例如下:object Test {   def main(args: Array[String]) {  val pattern = "(S|s)cala".r  val str = "Scala is scalable and cool"    println(pattern replaceFirstIn(str, "Java"))   }}执行以上代码,输出结果为:$ scalac Test.scala $ scala TestJava is scalable and cool16)Scala中的提取器(Extractor)概念:提取器是从传递给它的对象中提取出构造该对象的参数。说明;Scala 提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。提取器使用模式匹配在我们实例化一个类的时,可以带上0个或者多个的参数,编译器在实例化的时会调用 apply 方法。我们可以在类和对象中都定义 apply 方法。就像我们之前提到过的,unapply 用于提取我们指定查找的值,它与 apply 的操作相反。 当我们在提取器对象中使用 match 语句是,unapply 将自动执行,如下所示:17)Scala中的文件 I/O说明:Scala 进行文件写操作,直接用的都是 java中 的 I/O 类 (java.io.File):例子:import java.io._object Test {   def main(args: Array[String]) {  val writer = new PrintWriter(new File("test.txt" ))  writer.write("hello world")  writer.close()   }}执行以上代码,会在你的当前目录下生产一个 test.txt 文件,文件内容为"菜鸟教程":$ scalac Test.scala $ scala Test$ cat test.txt hello world从屏幕上读取用户输入:有时候我们需要接收用户在屏幕输入的指令来处理程序。实例如下:object Test {   def main(args: Array[String]) {  print("请输入: " )  val line = Console.readLine    println("谢谢,你输入的是: " + line)   }}执行以上代码,屏幕上会显示如下信息:$ scalac Test.scala $ scala Test请输入: hello world谢谢,你输入的是: hello world读取文件内容:使用 Scala 的 Source 类及伴生对象来读取文件。以下实例演示了从 "test.txt"文件中读取内容:例子:import scala.io.Sourceobject Test {   def main(args: Array[String]) {  println("文件内容为:" )  Source.fromFile("test.txt" ).foreach{  print   }   }}执行以上代码,输出结果为:$ scalac Test.scala $ scala Test文件内容为:test.txt文件中的内容几点注意:1)scala中没有i++和++i,只有 i = i + 1; 或 i += 1;

0 0
原创粉丝点击