scala学习笔记

Scalable 编程语言特点(可伸缩的,既可以编写小脚本,又可以写服务端的大程序)
  • 纯正的面向对象语言
  • 函数式语言
  • 无缝的Java互操作(建立在jvm基础上的)

SBT:Simple Build Tools
REPL:Read Evaluate Print Loop(交互式编程)(读取-求值-打印-循环)

启动REPL的两种方式:
  • 在cmd下输入scala
  • (安装sbt后)在cmd下输入sbt console
开发scala的IDE
  • The Scala IDE(basee on Eclipse) http://scala-ide.org/
  • IntelliJ IDEA with Scala plugin
  • Netbeans IDE with the Scala plugin
变量(三种变量修饰符)
  • val 定义immutable variable(常量)
  • var 定义mutable variable(变量)
  • lazy val(惰性求值的常量)

可以不显示指定变量的类型,因为Scala会自动进行类型推导

scala类型体

Byte(1个字节)/Short(2个字节)/Int(4个字节)/Long(8个字节)/Float/Double

Block(块)

{exp1;exp2}

{
exp1
exp2
}

Block也是一个表达式,其最终的求得的值是最后一个表达式的值

函数

def funcionName(param:ParamType):ReturnType = {
//function body:expressions
}

if表达式

if(logical_exp) valA else valB
if(true) 1 else 2
if表达式也是有返回值的,这一点不同于java

for表达式
for{
    x<- s
    y = x+1
    if(y>0)
}yield y
try表达式
try{}

catch{}

finally{}
try{

  Integer.parseInt("dog")

} catch{

  case _ => 0 //下划线通配所有对象

}finally{

  println("always be printed")

}
match表达式

//主要用在pattern match中

exp match{
  case p1 => val1
  case p2 => val2
  ...
  case _ => valn
}
code match{
  case 1 => "one"
  case 2 => "two"
  case _ => "others"
}
求值策略:

Scala里有两种求值策略(Evaluation Strategy)
1.Call By Value - 对参数实参求值,且仅求值一次
2.Call By Name - 参数实参每次在函数体内被用到时都会求值

Scala通常使用Call By Value
如果函数形参类型以 => 开头,那么会使用Call By Name
def foo(x: Int) = x //call by value
def foo(x: => Int) = x //call by name
举例:
def bar(x: Int,y: => Int):Int = 1
def loop():Int = loop //这是一个递归,死循环
下面两次调用bar:
bar(1,loop) //返回1
bar(loop,1) //一直进行死循环,不返回

函数是第一等公民

Scala语言支持:

  • 把函数作为实参传递给另外一个函数
  • 把函数作为返回值
  • 把函数赋值给变量
  • 把函数存储在数据结构里
    即在Scala中,函数就像普通变量一样,同样也具有函数的类型
函数类型

在Scala语言中,函数类型的格式为A => B,表示一个接受类型A的参数,并返回类型B的函数
例子:Int => String 是把整形映射为字符串的函数类型

高阶函数

用函数作为形参或返回值的函数,称为高阶函数

def operate(f:(Int,Int) => Int) = {
  f(4,4)
}

def greeting() = (name: String) => {"Hello"+" "+name} //这是一个匿名函数

匿名函数

匿名函数(Anonymous Function),就是函数常量,也称为函数文字量(Function Literal)
在Scala里,匿名函数的定义格式为:
(形参列表) => {函数体}

柯里化

柯里化函数(Curried Function)把具有多个参数的函数转换为一条函数链,每个节点上是单一参数。
例子:以下两个add函数定义是等价的
def add(x: Int,y: Int) = x + y
def add(x: Int)(y: Int) = x + y //Scala里柯里化的语法

例子:
def curriedAdd(a: Int)(b: Int) = a + b
curriedAdd(2)(2) // 4
val addOne = curriedAdd(1)_ //Int => Int

addOne(2) //3

递归函数

递归函数(Recursive Function)在函数式编程中是实现循环的一种技术
例子:计算n!

def factorial(n: Int) : Int ={
  if(n <= 0) 1
  else n * factorial(n - 1)
}

递归的天生缺陷就是效率低,递归到深处容易堆栈异常,所以要对递归进行优化------>尾递归函数
尾递归函数(Tail Recursive Function)中所有递归形式的调用都出现在函数的末尾
当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。

@annotation.tailrec //告诉scala编译器对下面这个函数进行递归优化,不加此注解,scala编译器是不会主动去优化的

def factorial(n: Int,m: Int): Int =
  if(n <= 0) m
  else factorial(n - 1,m * n)

调用:
factorial(5,1)


scala collection
List

常用操作:

  • ::
  • :::
  • head
  • tail
  • isEmpty
  • filter: 接收一个返回true/false的函数
    val a : List[Int] = List(1,2,3)
    a.filter(x => x % 2 ==1)
    "99 Red Balloons".toList得到List[Char] = List(9,9 ,R,e,d, ,B,a,l,l,o,o,n,s)
    "99 Red Balloons".toList.filter(x=>Character.isDigit(x))返回List[Char] = List(9,9)
  • takeWhile:也是接收一个返回true/false的函数
    "99 Red Balloons".toList.takeWhile(x=>x!='B')返回List[Char]=List(9,9, ,R,e,d, )
    到'B'那的时候得到false就终止了
  • map:接收一个映射的函数
    val c = List(x,y,z)
    c.map(x=>x.toUpperCase)返回List[String] = List(X,Y,Z)
    这里有一个简写方式就是""通配,即c.map(.toUpperCase)
    同样上边的filter也可以简写为a.filter(%2==1)
    可以连续使用:a.filter(
    % 2 == 1).map( _ + 10)得到List[Int] = LIst(11,13)
    val q = List(List(1,2,3),List(4,5,6))
    q.map(x=>x.filter(%2==0))返回List(List(2),List(4,6))
    也可以简写为q.map(
    .filter(_%2==0))
  • flatMap:
    上边的q可以q.flatMap(.filter(%2==0))得到List(2,4,6)
  • reduceLeft:归约操作
    val a = List(1,2,3)
    a.reduceLeft((x,y)=>x+y)返回6
    简写为a.reduceLeft(_ + _)返回6
  • foldLeft:
    a.foldLeft(0)(_ + )返回6
    a.foldLeft(1)(
    * _)返回6
Range:

1 to 10 得到Range(1,2,3,4,5,6,7,8,9,10)
1 to 10 by 2得到Range(1,3,5,7,9),其中2代表步长为2
(1 to 10).toList得到List(1,2,3,4,5,6,7,8,9,10)
1 until 10得到(1,2,3,4,5,6,7,8,9)

Stream:Stream is a lazy List

1 #:: 2 #::3 #:: Stream.empty得到Stream(1,?)
val stream = (1 to 100000000).toStream得到Stream(1,?)
类似List:
stream.head stream.tail 等

Tuple:元组

(1,2)
1 -> 2
(1,"Alice","Math",95.5)
访问元素:t._1,t._3
def sumSq(in:List[Int]):(Int,Int,Int)=in.foldLeft((0,0,0))((t,v)=>(t._1+1,t._2+v,t._3+v*v))

Map:

val p = Map(1 -> "David",9 -> "Elwood")
p(1)得到David
p.contains(1)返回true
p.keys得到Set(1,9)
p.values得到MapLike(David,Elwood)
p + (8 -> "Archer")
p - 1
p ++ List(2 -> "Alice",5 -> "Bob")
p -- List(1,9,2)

scala递归实现排序,代码特别简单:

def qSort(a:List[Int]):List[Int]=
  if(a.length<2) a
else qSort(a.filter(_<a.head)) ++ a.filter(_ == a.head) ++ qSort(a.filter(_ > a.head))
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • FP 3.1.函数 函数的地位和一般的变量是同等的,可以作为函数的参数,可以作为返回值。传入函数的任何输入是只读的...
    时待吾阅读 1,100评论 0 2
  • lang 2.1.和Java的异同 2.1.1.语法 Java++:增加的语法 -》纯OO;操作符重载;closu...
    时待吾阅读 2,352评论 0 0
  • scala学习笔记 第2章 变量和数据类型 基本数据 scala的核心数据为四种 :字面量、值、变量、类型 值使...
    485b1aca799e阅读 2,109评论 0 1
  • 22.13.main方法 Scala的main方法(类似java的static方法)必须定义在一个object内:...
    时待吾阅读 746评论 0 0
  • 当提笔写下《一根头发》这个题目时,我的内心一片荒芜,好似到处长满了草木,又好似没有一点生机,它充满感情而又机械般的...
    指茧阅读 343评论 0 0