Scala语言初入门

scala介绍

  • Scala语言来自于Scalable(可伸缩的)既可以写一些小的脚本,又可以写一写复杂的服务器端的程序。
  • Scala是一门纯正的面向对象语言,具有OO特征。
  • Scala是一门函数式语言,可以用函数式思想来编写代码
  • Scala是构建于JVM之上的,与java可以无缝互操作。

函数式编程思想

函数式编程基本名词介绍

纯函数来编写程序。

  • 纯函数(Pure Function),或函数的纯粹性(Purity)没有副作用(side Effect)
  • 副作用是状态的变化
    • 例子
    • 修改全局变量
    • 抛出异常
    • IO读写
    • 调用有副作用的函数
var x = 1
def XplusY_V1(y:Int) = x + y
def XplusY_V2(y:Int) = {x += y;x}

上面第一个函数是输入一个int类型的y,第二个函数是输入一个int类型的y返回值是x。
第二个函数相对于第一个函数对变量x产生了副作用。改变了x的值。
* 引用透明(Referential Transparency)对于相同的输入,总能得到相同的输出。
如果f(x)的参数x和函数体都是引用透明的,那么函数f是纯函数。
违反引用透明

  • 不变性(Immutability)为了获得引用透明性,任何值都不能发生变化。
  • 函数是一等公民(First-class Function)一切都是计算,函数式编程中只有表达式,变量、函数都是表达式。
    函数也可以作为参数或者返回值。

  • 表达式求值策略:严格求值和非严格求职。
    Call By Value属于严格求值
    Call By Name属于非严格求职

  • 惰性求值(Lazy Evaluation)当定义这个变量时不会立即求值,只有在使用到这个变量时才会求值。
  • 递归函数(Recursive Function)
    在函数式编程中没有循环语句,所有的循环都要用递归来实现。
    递归有个性能问题。容易堆栈溢出。

* 尾递归(Tail Recursion)

函数式编程的优点

  • 生产效率高
    同样的功能,Lisp(世界上第一个函数式编程语言)代码长度可能是C代码长度的七到十分之一。
  • 易于推理
  • 并行编程
    因为是纯函数,所以不会引起线程紊乱。
  • 多核计算、云计算

搭建scala环境

安装JDK

下载JDK最新版本,将环境变量添加到配置文件中

安装Scala的运行环境和包

http://www.scala-lang.org/download上下载了Scala的最新版本,将环境变量添加到配置文件中就可以用了。

REPL(Read Evaluate Print Loop)就是scala命令行的运行环境。

在linux命令行输入scala就可以直接进入到scala REPL中。

devil@devilshome:~$ scala
Welcome to Scala 2.12.0-M4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60).
Type in expressions for evaluation. Or try :help.

scala> println("Hello World")
Hello World

scala> 

println()函数在所有Scala代码中都可用。

scala> val x =1
x: Int = 1

scala> var x = 1
x: Int = 1

scala> 

var 和 val 的区别稍后解释。

使用eclipse开发scala

http://scala-ide.org/download/sdk.html下载专为scala的eclipse
- new一个Scala Project
- new 一个Scala Worksheet
worksheet是可以在IDE中直接进行代码的运行和结果的获得,是交互式的。
默认直接生成一个Object在eclipse中开发Scala

object worksheet {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet

  val x = 1                                       //> x  : Int = 1

  println(x)                                      //> 1

}

输入代码以后保存,会直接把输出的结果打印在右边。
新建一个package demo01
在package中新建一个scala app

package demo01

object Greeting extends App {
println("Hello,"+args(0)+"!")
}

运行时设置main class和参数,main class的格式为包名.类名。
设置main class
设置参数
在控制台查看打印输出的结果

Hello,Devil!

使用命令行编译scala

在文件夹中新建一个.scala文件,如Greeting.scala
在命令行中键入

devil@devilshome:~/example$ scalac Greeting.scala

编译完成后,原文夹下多了一个Greeting.class文件,这个就是编译后的字节码文件。
再对这个字节码文件进行使用。

devil@devilshome:~/example$ scala Greeting Jack
Hello,Jack!
devil@devilshome:~/example$ scala Greeting Devil
Hello,Devil!

变量和表达式

变量

  • var 自动生成读写接口,代表的是一个可变的有类型的存储单元。可以在定义变量时为它指定数据,而且可以在任何时间重新赋值。
  • val 只生成了只读接口是一个不可变得、有类型的存储单元。可以在定义值时为它指定数据,不过不允许重新赋值,代表是一种函数式的思维。val蕴含了final的语义。
  • lazy val 定义惰性求值的常量。
    可以不显示指定变量的类型,因为Scala会自动进行类型推导。
scala> val x=10
x: Int = 10

scala> val y :Int =20
y: Int = 20

scala> x+x
res0: Int = 20

scala> res0
res1: Int = 20

scala> res0*res1
res2: Int = 400

scala> z=200
<console>:16: error: reassignment to val
       z=200
        ^
//val的值不能被修改
scala> 
scala> val d = 20
d: Int = 20

scala> val e = 30
e: Int = 30

scala> lazy val f = d * e
f: Int = <lazy>

scala> f * 10
res3: Int = 6000

scala> f
res4: Int = 600

scala> 

精度问题

scala>  val b :Byte = 10
b: Byte = 10

scala> val x :Long = 10
x: Long = 10

scala> val y :Long = b
y: Long = 10

scala> val z : Byte = x
<console>:12: error: type mismatch;
 found   : Long
 required: Byte
       val z : Byte = x
                      ^

scala> 
  • 字符类型
scala> val q = 'X'
q: Char = X
  • Unit类型
    Scala中的Unit类型类似于java中的void。主要的不同是在Scala中可以有一个Unit类型值,也就是(),然而java中是没有void类型的值的。除了这一点,Unit和void是等效的。一般来说每一个返回void的java方法对应一个返回Unit的Scala方法。
scala> val u : Unit=()
u: Unit = ()

scala> val p = ()
p: Unit = ()
  • Nothing
    对于一个函数而言,如果返回值是nothing,则表名该函数发生了异常。
scala> def foo() = throw new Exception("error occurred")
foo: ()Nothing
  • String
    构建于java的String之上。
    新增了字符串插值(interpolation)的特性
scala> val name = "devil"
name: String = devil

scala> s"my name if ${name}"
res5: String = my name if devil
  • Block
    在scala中,代码块用于组织多个表达式,block也是一个表达式,其最终的求得的值是最后一个表达式的值。

函数

object func_wxamples {
  def hello(name: String): String = {
    s"hello,${name}"
  }                                               //> hello: (name: String)String
  hello("devil")                                  //> res0: String = hello,devil

  def hello2(name: String) = {
    s"hello,${name}"
  }                                               //> hello2: (name: String)String
    hello2("devil")                           //> res1: String = hello,devil

    def add (x:Int,y:Int) = x+y               //> add: (x: Int, y: Int)Int
    add(5,3)                                  //> res2: Int = 8

}

if表达式

在scala中,if是表达式,而不是语句。

object fun_if_example {
  if (true) 1 else 2                              //> res0: Int = 1
  if (false) 3 else 4                             //> res1: Int = 4

  val a = 1                                       //> a  : Int = 1
  if (a == 1) a                                   //> res2: AnyVal = 1
  if (a != 1) "不是1"                               //> res3: Any = ()
  if (a != 1) "不是1" else a                        //> res4: Any = 1
}

for循环

object fun_for_examples {

  val l = List("elisa", "sin", "satoshi")         //> l  : List[String] = List(elisa, sin, satoshi)

  for (
    s <- l //用s循环遍历l中的元素
  ) println(s)                                    //> elisa
                                                  //| sin
                                                  //| satoshi

  for (
    s <- l if (s.length > 3)
  ) println(s)                                    //> elisa
                                                  //| satoshi

  val result_for = for {
    s <- l
    s1 = s.toUpperCase()
    if (s1 != "")
  } yield (s1)                                    //> result_for  : List[String] = List(ELISA, SIN, SATOSHI)

}

yield (s1)的意思是将s放入一个新的collection中。

try表达式

try{}
catch{}
finally{}//无论有没有发生异常,我们都会执行finally这个代码块

match表达式

exp match{
    case p1 => val1
    case p2 => val2
    …
    case _ => valn
}
object func_match_example {
    val code = 3                              //> code  : Int = 3
    val result_match = code match{
        case 1 => "one"
        case 2 => "two"
        case _ => "three"
    }                                         //> result_match  : String = three
}

求值策略

scala里有两种求值策略(Evaluation Strategy)
- Call By Value 对函数实参求值,且仅求值一次
- 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
scala> def bar(x:Int,y: => Int)=1
bar: (x: Int, y: => Int)Int

scala> def loop(): Int = loop
loop: ()Int

scala> bar(1,loop)
res6: Int = 1

scala> bar(loop,1)

第二个bar(loop,1)在进行死循环,因为x是Call By Value的需要对所有表达式求值才能进行下一步运算。

高阶函数

scala中函数是第一等公民
Scala语言支持:
1. 把函数作为实参传递给另外一个函数
2. 把函数作为返回值
3. 把函数赋值给变量
4. 把函数存储在数据结构中
在scala中,函数就像普通变量一样,同样也具有函数类型。

  • 在scala中,函数类型的格式为 A=>B,表示一个接收类型A的参数,并返回类型B的函数。

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


匿名函数
就是函数常量,也成为函数文字量。
在scala里,匿名函数的定一个是为(形参列表)=>{函数体}

柯里化

柯里化函数把具有多个参数的函数转换为一条函数链,每个节点上是单一参数。

eg:下面两个函数的定义是等价的

def add(x: Int,y: Int) = x+y
def add(x: Int)(y: Int) = x+y

递归函数

递归函数在函数式变成中是实现循环的一种技术。

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

尾递归
尾递归函数中所有递归形式的调用都出现在函数的末尾。
当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。
避免堆栈溢出

    @annotation.tailrec //告诉scala编译器,对这个递归进行尾递归优化
    def factorial(n: Int,m: Int): Int =
        if (n<=0) m
        else factorial(n-1,m*n)

    factorial(5,1)

在上面这个案例增加了一个m,m其实是保留了n*n-1*n-2……这样一个累乘器。
m永远拿到都是过去几次累乘的结果。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Scala语言是一种功能强大的静态类型编程语言,适用于多个方面的开发需求。 首先,Scala语言能够在Java虚拟机(JVM)上运行,这意味着它可以与现有的Java代码和库无缝集成。Scala既可以与Java代码互操作,也可以使用Java库,为Java开发人员提供了一个平滑过渡到Scala的路径。此外,Scala还支持与其他JVM语言(如Groovy和Kotlin)的互操作性,使得开发者可以使用统一的开发生态系统。 其次,Scala语言支持函数式编程和面向对象编程的混合,这极大地增加了开发人员的灵活性和代码的可读性。函数式编程的核心思想是将计算视为数学函数的求值,并使用不可变数据结构和高阶函数来编写可复用和可测试的代码。而面向对象编程则强调将数据和对数据的操作封装到对象中,提供更好的抽象和封装能力。Scala的混合编程范式可以更好地满足不同项目的需求,并且使得编写模块化、可维护和可扩展的代码变得更加容易。 第三,Scala提供了一套强大的特性和工具,使得开发者可以更加高效地编写复杂的应用程序。其中包括灵活的类型推导、模式匹配、高级集合操作、并发编程支持等等。Scala还引入了一种表达式力强大且具有可组合性的语法,使得代码看起来更加简洁、优雅。 因此,Scala语言被广泛应用于各种领域的开发,包括大数据处理、Web应用开发、分布式系统、科学计算等等。它的灵活性和可扩展性使得开发者能够更好地应对复杂的业务需求和技术挑战。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值