高逼格实用编程语言
用joern查询的时候,顺带学了一门新语言…
背景
- 名字:来源于scalable这个词
- 纯正的面向对象语言
- 函数式语言
- 无缝的java互操作
函数式编程语言
纯函数来编写程序
函数式编程是一种计算机编程范式,把计算当成
纯函数(pure function),就是没有副作用的函数。函数的副作用指的是状态的变化。就是函数不会改变变量的值。
例如:
var x = 1
def XplusY_V1(y:Int) = x + y//pure function
def XplusY_V2(y: Int)= {x+y;x}//not pure function
引用透明:对于相同的输入,总是得到相同的输出。
如果f(x)的参数x和函数体都是引用透明的,那么函数f是纯函数。比如append就不是纯函数。
函数是一等公民,一切都是计算,函数式编程只有表达式。变量函数都是表达式,函数可以作为一个函数的一个参数,或者函数可以返回一个函数。
高阶函数指的是一个函数可以作为另外一个函数的输入和输出。
闭包:
求值:
- 严格求值
- 非严格求值
递归函数:(递归的层数太深会导致栈溢出)
- 递归实现循环
- 尾递归
函数式编程的优点:
- 生产效率高:同样功能的程序是C程序的1/7
- 易于推理
- 多核计算和云计算
基本语法
scala的变量
三种变量修饰符
- val 定义immutable variable
- var 定义 mutable variable
- lazy val定义惰性变量(用到这个变量的时候才求值)
字符串插值
val name="iskinder"
s"my name is ${name}"
scala的类型体系
Any
- AnyVal
- Numeric types
- Boolean
- Char
- Unit
- AnyRef
- All java.* ref types
- All scala.* ref types
代码块
两种写法:
{
exp1
exp2
}
{exp1;exp2}
if表达式
if (a!=1) "not one"
if (a!=1) "not one" else a
for comprehension
val l = List("alice","bob")
for{
s<- l
}println(s)
$ alice bob
val result_for = for {
s <- l
s1 = s.toUpperCase()
if(s1 != "")
}yield(s1)
$ result_for: List[String] = List(ALICE, BOB)
try 表达式
try{
Integre.parseInt("dog")
}catch{
case _ => 0
}finally{
println("always be printed")
}
match表达式
和switch很相似
code match{
case 1 => "one"
case 2 => "two"
case _ => "others"
}
求值策略
call by value
对函数实参求值,且求值一次
def test1(x:Int,y:Int): Int = x*x
求值步骤:
- test1(3+4,8)
- test1(7,8)
- 7*7
- 49
call by name
函数实参在每次函数体内被用到时都会求值
def test2(x: => Int, y: => Int): Int = x * x
求值步骤:
- test2(3+4,8)
- (3+4)*(3+4)
- 7*(3+4)
- 7*7
- 49
总结:call by value 和call by name的区别在于call by value会对函数实参进行求值,然后得到值后,把值放进去函数内进行运算。call by name则是只有在函数体内用到这个实参时候,才会对他进行求值。如果没有用到就不会进行求值。
高阶函数
函数是第一等公民
Scala支持以下特性:
- 把函数作为实参传递给另外一个函数
- 把函数作为返回值
- 把函数赋值给变量
- 把函数存在数据结构里
函数类型:
A => B //接受类型A的参数,返回类型B的函数
Int => String // 把整形映射为字符串的函数类型
一个简单的例子:
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
高阶函数:函数作为形参或返回值的函数
def operate(f:(Int,Int)=>Int)={
f(4,4)
}
def greeting() = (name:String) => {"hello"+" "+name}
匿名函数:函数常量
匿名函数的定义格式为:(形参列表)=>{函数体}
例子:
var add = (x:Int,y:Int)=>x+y
add(2,3)//output 5
柯里化
柯里化(Curried Function)把具有多个参数的函数转换为一条函数链,每个节点上是单一参数。
例子:
def curriedAdd(a:Int)(b:Int)=a+b
curriedAdd(2)(2) //4
val addOne = curriedAdd(1)_
addOne(2) //3
递归函数
递归函数在函数式编程中是实现循环的一种技术。
例子:n!
def factorial(n:Int):Int=
if(n<=0) 1
else n*factorial(n-1)
尾递归:所有递归形式的调用都出现在函数的末尾(主要解决递归层数过多导致栈溢出)
@abbitation.tailrec
def factorial(n:Int, m:Int):Int=
if(n<=0) m
else factorial(n-1,m*n)
Collection
List[T]用法
val a = List(1,2,3,4)//(1,2,3,4)
val b = 0:: a //(0,1,2,3,4)
val c = "x" :: "y" ::"z"::Nil//(x,y,z),从z开始连接
val d = a ::: c//List[Any] = (1,2,3,4,x,y,z)
a.head // 1
d.head // 1
c.head // x
a.tail // (2,3,4)
c.tail //(y,z)
a.isEmpty // Boolean = false
Nil.isEmpty // Boolean = true
遍历list
def walkthru(1:List[Int]):String={
if(l.isEmpty) ""
else l.head.toString+" "+walkthru(l.tail)
}
高级使用:
a.filter(x=>x%2==1)//List(1,2)
"99 red ballons".toList//List(9,9, ,r,e,d, ,b,a,l,l,o,o,n,s)
"99 red ballons".toList.filter(x=>Character.isDigit(x))//9,9
"99 red ballons".toList.takeWhile(x=>x!='b')//9,9,r,e,d
map
c.map(x=> x.toUpperCase)//X,Y,Z
val q = List(a, List(4,5,6))
q.map(_.filter(_ % 2 ==0))//(List(2),List(4,6))
q.flatMap(_.filter(_ % 2 ==0))//2,4,6
reduceLeft
reduceLeft(op:(T,T)=>T)
a.reduceLeft((x,y)=>x+y)//6
a.reduce(_+_)//6
foldLeft
foldLeft(z:U)(op:(U,T)=>U)
a.foldLeft(0)(_ + _)//0+1+2+3=6
a.foldLeft(1)(_ * _)//1*1*2*3=6
Range
1 to 5 //Range(1,2,3,4,5)
1 to 10 by 2 //Range(1,3,5,7,9)
(1 to 10).toList //List(1,2,3,4,5,6,7,8,9,10)
1 until 10 //Range(1,2,3,4,5,6,7,8,9)
Stream
lazy list - 按需求值。
1 #:: 2 #:: 3 #:: Stream.empty //Stream(1,?)
val stream = (1 to 10000).toStream // Stream(1,?)
Tuple
有点像数据库的记录
val tp1 = (1,2) //pair
1 -> 2 //(1,2)
(1,"Alice","math",95.8)//
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", 2 -> "Elwood")
p(1) //String=David
p.contains(1)//true
p.contains(3)//false
p.keys//(1,9)
p.values//(David,Elwood)
p + (8 -> "archer" )//add 8
p - 1 //delete 1
p ++ List(3-"Alice",5->"Bob")
p -- List(1,2,3)
参考链接
慕课网scala的基础教程:https://www.imooc.com/learn/613
scala教程—菜鸟教程:https://www.runoob.com/scala/scala-tutorial.html