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
}
}
}*/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。