本文转载自微信公众号“吹笛蛋窝”,作者吹笛蛋。转载本文请联系派珀蛋巢公众号。不接触Scala就很难开始使用Spark。Scala似乎为java提供了很多“类似于函数式编程”的语法糖。这里记录下这门语言的独特之处,分享给读者朋友们。参考资料主要有:曹杰。Spark大数据分析技术(Scala版)[M].北京航空航天大学出版社,2021.ISBN:9787512433854陈欢,林世飞.Spark最佳实践[M].人民邮电出版社,2016.ISBN:9787115422286Scala的基本思想和思考Sacla是ScalableLanguage,顾名思义,是一种可扩展的编程语言:基于Java的虚拟机(Scala会被编译成JVM字节码)但是可以用作脚本的是一种静态语言,但它可以像动态语言一样支持交互式编程。表面对象:每一个值都是一个对象,每一个操作都是一个方法调用。函数式编程:所有的函数都是对象,函数是“一等公民”。Scala中几乎所有东西都是表达式。scala是一个解释器,而scalac是一个编译器;可以直接scalatest.scala,或者scalactest.scala&scalatest(先把源码编译成字节码,然后把字节码放到虚拟机中解释运行)。您也可以通过键入scala进入交换编程界面。所以需要注意的是需要先安装JDK并设置环境变量JAVA_HOME。此外,更重要的是,Scala次要版本是兼容的:2.12.x和2.13.x不兼容,但2.12.10和2.12.11兼容。最基本语法示例类型声明、控制结构(for、模式匹配、case)//变量valtwo:Int=1+1varone:Int=1varone:String='one'//functiondefaddOne(x:Int):Int=x+1defadd(x:Int,y:Int):Int={x+y}//部分控制结构varfilename=if(!args.isEmpty)args(0)else"default.txt"for(i<-1to4)println("iteration"+i)1到4是[1,2,3,4]而i到4是[1,2,3]。关于for有一些技巧和窍门。//多个区间for(a<-1to2;b<-1to2){println("a:"+a+",b:"+b)}//结果a:1,b:1a:1,b:2a:2,b:1a:2,b:2//过滤器vallist1=List(3,5,2,1,7)for(x<-list1ifx%2==1)print(""+x)//3517有更多关于模式匹配的技巧。这里我直接参考:scala中case的用法[1]//1。简单匹配,值匹配:valbools=List(true,false)for(bool<-bools){boolmatch{casetrue=>println("heads")casefalse=>println("tails")case_=>println("somethingotherthanheadsortails(哎呀!)")}}importscala.util.RandomvalrandomInt=newRandom().nextInt(10)randomIntmatch{case7=>println("luckyseven!")caseotherNumber=>println("boo,gotboringol'"+otherNumber)}//2。类型匹配valsundries=List(23,"Hello",8.5,'q')for(sundry<-sundries){sundrymatch{casei:Int=>println("gotanInteger:"+i)cases:String=>println("gotaString:"+s)casef:Double=>println("gotaDouble:"+f)caseother=>println("gotsomethingelse:"+other)}}//三个按顺序匹配valwillWork=List(1,3,23,90)valwillNotWork=List(4,18,52)valempty=List()for(l<-List(willWork,willNotWork,empty)){lmatch{caseList(_,3,_,_)=>println("四元素,第二个为'3'。")caseList(_*)=>println("Anyotherlistwith0ormoreelements.")}}//四种情况下使用守卫数组匹配valtupA=("Good","Morning!")valtupB=("Guten","Tag!")for(tup<-List(tupA,tupB)){tupmatch{case(thingOne,thingTwo)ifthingOne=="Good"=>println("以'Good'开头的双元组。")case(thingOne,thingTwo)=>println("Thisshastwothings:"+thingOne+"and"+thingTwo)}}//五物体深度匹配caseclassPerson(name:String,age:Int)valalice=newPerson("Alice",25)valbob=newPerson("Bob",32)valcharlie=newPerson("Charlie",32)for(person<-List(alice,bob,charlie)){personmatch{casePerson("Alice",25)=>println("HiAlice!")casePerson("Bob",32)=>println("HiBob!")casePerson(name,age)=>println("Whoareyou,"+age+"year-oldpersonnamed"+name+"?")}}//六个正则表达式匹配valBookExtractorRE="""Book:title=([^,]+),\s+authors=(.+)""".rvalMagazineExtractorRE="""Magazine:title=([^,]+),\s+issue=(.+)""".rvalcatalog=List("Book:title=ProgrammingScala,authors=DeanWampler,AlexPayne","杂志:title=TheNewYorker,issue=January2009","Book:title=WarandPeace,authors=LeoTolstoy","Magazine:title=TheAtlantic,issue=February2009","BadData:text=Whoputthishere??")for(item<-catalog){itemmatch{caseBookExtractorRE(title,authors)=>println("Book\""+title+"\",writtenby"+authors)caseMagazineExtractorRE(title,issue)=>println("杂志\""+title+"\",issue"+issue)caseentry=>println("Unrecognizedentry:"+entry)}}关于case,我想强调一下它在"解包"中的应用:dict=Map("Piper"->95,"Bob"->90)dict.foreach{case(k,v)=>printf("gradeof%sis%s/n",k,v)}gradeofPiperis95gradeofBobis90以上:使用foreach{case()=>{}},注意foreach花括号等效于以下内容。dict=Map("Piper"->95,"Bob"->90)dict.foreach(x=>println(s"gradeof${x._1}is${x._2}"))gradeofPiperis95gradeofBobis90Scala语法独特的地方没有参数方法,调用时不需要加括号:args.isEmpty。defwidth:Int=if(height==0)0elsecontents(0).lengthwidth//调用for时使用<-,相当于Python的in。继承使用关键字extends:classA(a:Int)extendsB。对象中定义了单实例对象/静态成员变量和方法:objectTimer{varcount=0defcurrentCount():Long={count+=1count}}Timer.currentCount()//直接调用classTimer{...}函数返回是不需要加return,默认最后一个表达式。函数式:匿名函数作为参数,也可以更简洁valnumbers=List(1,-3,-5,9,0)numbers.filter((x)=>x>0)numbers.filter(x=>x>0)numbers.filter(_>0)//当一个参数在函数中只使用一次时,_有特殊的意义和作用(占位符)//部分应用的函数defadder(m:Int,n:Int)=m+nvaladd2=adder(2,_:Int)//add2:(Int)=>Int=
