Scala入门教程详解
Scala简介
Scala(ScalaLanguage的简称)语言是一种能够运行于JVM和.Net平台之上的通用编程语言,既可用于大规模应用程序开发,也可用于脚本编程,它由由MartinOdersk于2001开发,2004年开始程序运行在JVM与.Net平台之上,由于其简洁、优雅、类型安全的编程模式而受到关注。
Scala语言具有如下特点:
1纯面向对象编程语言
(1)Encapsulation/informationhiding.
(2)Inheritance.
(3)Polymorphism/dynamicbinding.
(4)Allpredefinedtypesareobjects.
(5)Alloperationsareperformedbysendingmessagestoobjects.
(6)Alluser-definedtypesareobjects.
2函数式编程语言
定义:Functionalprogrammingisaprogrammingparadigmthattreatscomputationastheevaluationofmathematicalfunctionsandavoidsstateandmutabledata.
函数式编程语言应支持以下特性:
(1)高阶函数(Higher-orderfunctions)
(2)闭包(closures)
(3)模式匹配(Patternmatching)
(4)单一赋值(Singleassignment)
(5)延迟计算(Lazyevaluation)
(6)类型推导(Typeinference)
(7)尾部调用优化(Tailcalloptimization)
(8)类型推导(Typeinference)
3Scala语言具有很强的兼容性、移植性
Scala运行于JVM上,能够与JAVA进行互操作,具有与JAVA一样的平台移植性
Scala示例
/** * *scala是一门多范式编程语言,集成了面向对象编程和函数式编程等多种特性。 *scala运行在虚拟机上,并兼容现有的Java程序。 *Scala源代码被编译成java字节码,所以运行在JVM上,并可以调用现有的Java类库。 */ /** *第一个Scala程序 *Scala和Java最大的区别是:Scala语句末尾的分号(;)是可选的! *编译运行: *先编译:scalacHelloScala.scala将会生成两个文件:HelloScala$.class和HelloScala.class *在运行:scalaHelloScala *输出结果:helloscala!!! * *objectHelloScala{ defmain(args:Array[String]):Unit={ println("helloscala!!!") } } */ /** *Scala基本语法: *区分大小写 *类名首字母大写(MyFirstScalaClass) *方法名称第一个字母小写(myMethodName()) *程序文件名应该与对象名称完全匹配 *defmain(args:Array[String]):scala程序从main方法开始处理,程序的入口。 * *Scala注释:分为多行/**/和单行// * *换行符:Scala是面向行的语言,语句可以用分号(;)结束或换行符(println()) * *定义包有两种方法: *1、packagecom.ahu *classHelloScala *2、packagecom.ahu{ *classHelloScala *} * *引用:importjava.awt.Color *如果想要引入包中的几个成员,可以用selector(选取器): *importjava.awt.{Color,Font} *//重命名成员 *importjava.util.{HashMap=>JavaHashMap} *//隐藏成员默认情况下,Scala总会引入java.lang._、scala._和Predef._,所以在使用时都是省去scala.的 *importjava.util.{HashMap=>_,_}//引入了util包所有成员,但HashMap被隐藏了 */ /** *Scala数据类型: *Scala与Java有着相同的数据类型,下面列出一些Scala有的数据类型。 *Unit:表示无值,和其他语言的void一样。 *Null:null或空引用。 *Nothing:是Scala的类层级的最低端,是任何其他类型的子类型。 *Any:是所有其他类的超类。 *AnyRef:是Scala所有引用类的基类。 * *多行字符串的表示方法: valfoo="""第一行 第二行 第三行""" */ /** *Scala变量: *在Scala中,使用关键字“var”声明变量,使用关键字“val”声明常量。 *varmyVar1:String="foo" *varmyVar2:Int *valmyVal="Hello,Scala!" *Scala多个变量声明: *valxmax,ymax=100//xmax,ymax都声明为100 */ /** *Scala访问修饰符: *Scala访问修饰符和Java基本一样,分别有private、protected、public。 *默认情况下,Scala对象的访问级别是public。 * *私有成员:用private关键字修饰的成员仅在包含了成员定义的类或对象内部可见。 *classOuter{ *classInner{ *privatedeff(){println("f")} *classInnerMost{ *f()//正确 *} *(newInner).f()//错误 *} *} * *保护成员:Scala比Java中更严格。只允许保护成员在定义了该成员的类的子类中被访问。 *packagep{ *classSuper{ *protecteddeff(){println("f")} *} *classSubextendsSuper{ *f() *} *classOther{ *(newSuper).f()//错误 *} *} * *公共成员:默认public,这样的成员在任何地方都可以被访问。 *classOuter{ *classInner{ *deff(){println("f")} *classInnerMost{ *f()//正确 *} *} *(newInner).f()//正确 *} * *作用域保护:Scala中,访问修饰符可以通过使用限定词强调。 *private[x]或者protected[x] *private[x]:这个成员除了对[...]中的类或[...]中的包中的类及他们的伴生对象可见外,对其他的类都是private。 */ /** *Scala运算符:和Java一样,这里就不再浪费时间一一介绍了。 *算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符。 */ /** *Scalaif...else语句:和Java一样,简单列举一下四种情况。 *if(...){ * *} * *if(...){ * *}else{ * *} * *if(...){ * *}elseif(...){ * *}else{ * *} * *if(...){ *if(...){ * *} *} */ /** *Scala循环:和Java一样,这里不赘述,只介绍三种循环类型。 *while循环、do...while循环、for循环 */ /** *Scala函数:用一个例子来说明函数的定义和函数调用。 *objectTest{ *defmain(args:Array[String]){ *println(addInt(1,3));//函数调用 *} *defaddInt(a:Int,b:Int):Int={//函数定义 *varsum:Int=0 *sum=a+b *returnsum *} *} */ /** *Scala闭包: *闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。 *例子: *objectTest{ *defmain(args:Array[String]){ *println("muliplier(1)value="+muliplier(1)) *println("muliplier(2)value="+muliplier(2)) *} *varfactor=3//定义在函数外的自由变量 *valmuliplier=(i:Int)=>i*factor//muliplier函数变量就是一个闭包 *} *输出结果: *muliplier(1)value=3 *muliplier(2)value=6 */ /** *Scala字符串: * *Scala中可以创建两中字符串:一种是不可修改的,一种是可以修改的。 *//创建不可修改的字符串 *valgreeting:String="HelloWorld!"; *//创建可以修改的字符串 *objectTest{ *defmain(args:Array[String]){ *valbuf=newStringBuilder; *buf+='a'//添加一个字符 *buf++="bcdef"//添加一个字符串 *println(buf.toString);//输出:abcdef *} *} * *字符串长度:xxx.length() * *字符串连接:可以用concat()方法或者用加号 *objectTest{ defmain(args:Array[String]){ varstr1="字符串1:"; varstr2="字符串2"; varstr3="字符串3:"; varstr4="字符串4"; println(str1+str2);//字符串1:字符串2 println(str3.concat(str4));//字符串3:字符串4 } } * *创建格式化字符串: *String类中可以使用printf()方法来格式化字符串并输出。 *objectTest{ *defmain(args:Array[String]){ *varfloatVar=12.456 *varintVar=2000 *varstringVar="字符串变量" *varfs=printf("浮点型变量为"+ *"%f,整形变量为%d,字符串为"+ *"%s",floatVar,intVar,stringVar) *println(fs)//浮点型变量为12.456000,整型变量为2000,字符串为字符串变量 *} *} */ /** *Scala数组: *1、声明数组 *varz:Array[String]=newArray[String](3)或者varz=newArray[String]() *z(0)="value1";z(1)="value2";z(2)="value3" * *varz=Array("value1","value2","value3") * *2、处理数组 *objectTest{ *defmain(args:Array[String]){ *varmyList=Array(1.1,2.2,3.3,4.4) * *//输出所有数组元素 *for(x<-myList){ *println(x) *} * *//计算数组所有元素的总和 *vartotal=0.0 *for(i<-0to(myList.length-1)){ *total+=myList(i) *} *println("总和:"+total) * *//查找数组中的最大元素 *varmax=myList(0) *for(i<-1to(myList.length-1)){ *if(myList(i)>max) *max=myList(i) *} *println("最大值:"+max) *} *} * *3、多维数组 *importArray._ *objectTest{ *defmain(args:Array[String]){ *//定义数组 *varmyMatrix=ofDim[Int](3,3) *//创建矩阵 *for(i<-0to2){ *for(j<-0to2){ *myMatrix(i)(j)=j; *} *} *//打印矩阵 *for(i<-0to2){ *for(j<-0to2){ *print(""+myMatrix(i)(j)); *} *println(); *} *} *} * *4、合并数组 *importArray._ *objectTest{ *defmain(args:Array[String]){ *varmyList1=Array(1.1,2.2,3.3,4.4) *varmyList2=Array(5.5,6.6,7.7,8.8) *//使用concat()合并 *varmyList3=concat(myList1,myList2) *//输出所有数组元素 *for(x<-myList3){ *println(x) *} *} *} * *5、创建区间数组:使用range(x,y,z)创建区间数组,数值范围大于等于x,小于y。z表示步长,默认为1。 *objectTest{ *defmain(args:Array[String]){ *varmyList1=range(10,20,2) *varmyList2=range(10,20) *for(x<-myList1){ *print(""+x)//输出:1012141618 *} *println() *for(x<-myList2){ *print(""+x)//输出:10111213141516171819 *} *} *} */ /** *Scala集合:分为可变集合和不可变集合。 *可变集合:可以在适当的地方被更新或扩展,也就是可以修改、添加、移除一个集合的元素。 *不可变集合:永远不会改变。但可以模拟添加、移除、更新操作,但是这些操作将在每一种情况下都返回一个新的集合, *同时使原来的集合不发生改变。 *//定义整形List *valx=List(1,2,3,4) *//定义Set *varx=Set(1,3,5,7) *//定义Map *valx=Map("one"->1,"two"->2,"three"->3) *//创建两个不同类型的元组 *valx=(10,"Runoob") *//定义Option *valx:Option[Int]=Some(5) */ /** *Scala迭代器: *迭代器不是一个集合,而是一个用于访问集合的方法。 * */ /*objectTest{ defmain(args:Array[String]):Unit={ valit=Iterator("one","two","three","four") while(it.hasNext){//检测集合中是否还有元素 println(it.next())//返回迭代器的下一个元素,并更新迭代器的状态 } valita=Iterator(1,2,3,4,5) valitb=Iterator(11,22,33,44,55) //println(ita.max)//查找最大元素 //println(itb.min)//查找最小元素 println(ita.size)//获取迭代器的长度 println(itb.length)//获取迭代器的长度 } }*/ /** *Scala类和对象: *类是对象的抽象,对象是类的具体实例。 *类是抽象的,不占用内存;对象是类的具体实例,占用存储空间。 * */ /*importjava.io._ classPoint(xc:Int,yc:Int){ varx:Int=xc vary:Int=yc defmove(dx:Int,dy:Int):Unit={ x=x+dx y=y+dy println("x点的坐标是:"+x) println("y点的坐标是:"+y) } } objectTest{ defmain(args:Array[String]):Unit={ valpt=newPoint(10,20) //移到一个新的位置 pt.move(10,10) } }*/ /** *Scala继承:跟Java差不多。 *1、重写一个非抽象方法必须使用override修饰符 *2、只有主构造函数才可以往基类的构造函数里写参数 *3、在子类中重写超类的抽象方法时,不需要使用override */ /*classPoint(valxc:Int,valyc:Int){ varx:Int=xc vary:Int=yc defmove(dx:Int,dy:Int):Unit={ x=x+dx y=y+dy println("x点的坐标是:"+x) println("y点的坐标是:"+y) } //------------------------------------- varname="" overridedeftoString=getClass.getName+"[name="+name+"]" } classLocation(overridevalxc:Int,overridevalyc:Int, valzc:Int)extendsPoint(xc,yc){//继承重写了父类的字段 varz:Int=zc defmove(dx:Int,dy:Int,dz:Int){ x=x+dx y=y+dy z=z+dz println("x点的坐标是:"+x) println("y点的坐标是:"+y) println("z点的坐标是:"+z) } //--------------------------------------- varsalary=0.0 overridedeftoString=super.toString+"[salary="+salary+"]" } objectTest{ defmain(args:Array[String]):Unit={ valloc=newLocation(10,20,30) loc.move(10,10,5) //------------------------------------ loc.name="lc" loc.salary=35000.0 println(loc) } }*/ /** *Scala单例对象: *Scala中没有static,要使用object关键字实现单例模式。 *Scala中使用单例模式时,除了定义类,还要定义一个同名的object对象,它和类的区别是,object对象不能带参数。 *当单例对象与某个类共享一个名称时,他被称作这个类的伴生对象。 *必须在同一个源文件里定义类和它的伴生对象。 *类和它的伴生对象可以互相访问其私有成员。 */ /*//私有构造方法 classMarkerprivate(valcolor:String){ println("创建"+this) overridedeftoString():String="颜色标记:"+color//4:颜色标记:red } //伴生对象,与类共享名字,可以访问类的私有属性和方法 objectMarker{ privatevalmarkers:Map[String,Marker]=Map( "red"->newMarker("red"),//1:创建颜色标记:red "blue"->newMarker("blue"),//2:创建颜色标记:blue "green"->newMarker("green")//3:创建颜色标记:green ) defapply(color:String)={ if(markers.contains(color))markers(color)elsenull } defgetMarker(color:String)={ if(markers.contains(color))markers(color)elsenull//5:颜色标记:blue } defmain(args:Array[String]){ println(Marker("red")) //单例函数调用,省略了.(点)符号 println(MarkergetMarker"blue") } }*/ /** *ScalaTrait(特征): *相当于Java的接口,但比接口功能强大,它还可以定义属性和方法的实现。 *一般情况下Scala的类只能单继承,但特征可以实现多重继承。 */ /*//定义特征 traitEqual{ defisEqual(x:Any):Boolean//未实现的方法 defisNotEqual(x:Any):Boolean=!isEqual(x)//实现了的方法 } classPoint(xc:Int,yc:Int)extendsEqual{ varx:Int=xc vary:Int=yc overridedefisEqual(obj:Any):Boolean= obj.isInstanceOf[Point]&& obj.asInstanceOf[Point].x==x } objectTest{ defmain(args:Array[String]):Unit={ valp1=newPoint(2,3) valp2=newPoint(2,4) valp3=newPoint(3,3) println(p1.isNotEqual(p2)) println(p1.isNotEqual(p3)) println(p1.isNotEqual(2)) } }*/ /** *特征构造顺序: *构造器的执行顺序: *1、调用超类的构造器 *2、特征构造器在超类构造器之后、类构造器之前执行 *3、特征由左到右被构造 *4、每个特征当中,父特征先被构造 *5、如果多个特征共有一个父特征,父特征不会被重复构造 *6、所有特征被构造完毕,子类被构造 */ /** *Scala模式匹配: *选择器match{备选项} */ /*objectTest{ defmain(args:Array[String]):Unit={ println(matchTest("two")) println(matchTest("test")) println(matchTest(1)) println(matchTest(6)) } defmatchTest(x:Any):Any=xmatch{ case1=>"one" case"two"=>2 casey:Int=>"scala.Int"//对应类型匹配 case_=>"many"//默认全匹配选项 } }*/ /** *使用样例类: *使用case关键字的类定义就是样例类,样例类是种特殊的类,经过优化以用于模式匹配。 */ /*objectTest{ defmain(args:Array[String]):Unit={ valalice=newPerson("Alice",25) valbob=newPerson("Bob",32) valcharlie=newPerson("Charlie",27) for(person<-List(alice,bob,charlie)){ personmatch{ casePerson("Alice",25)=>println("HiAlice!") casePerson("Bob",32)=>println("HiBob!") casePerson(name,age)=>println("Age:"+age+"year,name:"+name+"?") } } } //样例类 caseclassPerson(name:String,age:Int) }*/ /** *Scala正则表达式: *和Java差不多,在用的时候查一下就行了。 */ /** *Scala异常处理: *和Java类似。在Scala中借用了模式匹配的方法来在catch语句块中来进行异常匹配。 */ /*importjava.io.{FileNotFoundException,FileReader,IOException} objectTest{ defmain(args:Array[String]):Unit={ try{ valf=newFileReader("input.txt") }catch{ caseex:FileNotFoundException=>{ println("Missingfileexception") } caseex:IOException=>{ println("IOException") } }finally{ println("Exitingfinally...") } } }*/ /** *Scala提取器(Extractor): *apply方法:无需new操作就可创建对象。 *unapply方法:是apply方法的反向操作,接受一个对象,然后从对象中提取值,提取的值通常是用来构造对象的值。 */ /*objectTest{ defmain(args:Array[String]){ println("Apply方法:"+apply("Zara","gmail.com"));//也可直接Test("Zara","gmail.com")来创建Zara@gmail.com println("Unapply方法:"+unapply("Zara@gmail.com")); println("Unapply方法:"+unapply("ZaraAli")); } //注入方法(可选) defapply(user:String,domain:String)={ user+"@"+domain } //提取方法(必选) defunapply(str:String):Option[(String,String)]={ valparts=strsplit"@" if(parts.length==2){ Some(parts(0),parts(1)) }else{ None } } }*/ /** *提取器使用模式匹配: *在我们实例化一个类的时,可以带上0个或者多个的参数,编译器在实例化的时会调用apply方法。 */ /*objectTest{ defmain(args:Array[String]){ valx=Test(5) println(x) xmatch { caseTest(num)=>println(x+"是"+num+"的两倍!")//2:10是5的两倍! //unapply被调用 case_=>println("无法计算") } } defapply(x:Int)=x*2//1:10 defunapply(z:Int):Option[Int]=if(z%2==0)Some(z/2)elseNone }*/ /** *Scala文件I/O: * */ /*//文件写操作 importjava.io._ objectTest{ defmain(args:Array[String]){ valwriter=newPrintWriter(newFile("test.txt")) writer.write("Scala语言") writer.close() } }*/ //从屏幕上读取用户输入 /*objectTest{ defmain(args:Array[String]){ print("请输入菜鸟教程官网:") valline=Console.readLine//在控制台手动输入 println("谢谢,你输入的是:"+line) } }*/ //从文件上读取内容 /*importscala.io.Source objectTest{ defmain(args:Array[String]){ println("文件内容为:") Source.fromFile("test.txt").foreach{ print } } }*/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。