zoukankan      html  css  js  c++  java
  • Scala入门学习随笔

    推荐学习视频:慕课网http://www.imooc.com/learn/613,讲师:辰风

    ScalaAPI:http://www.scala-lang.org/api/current/#package

    -------------

    简介

    -------------

    ■函数式编程是什么鬼?

    就是只用纯函数来编写程序

    ■函数式编程的重要概念

    •纯函数(Pure Function)、或函数的纯粹性(Purity)、没有副作用(Side Effect)

    副作用是状态的变化(Mutation)

    例如:修改全局变量、跑出异常、IO读写、调用邮副作用的函数

    •引用透明(Referential Transparency)

    对于相同的输入,总是得到相同的输出

    如果f(x)的参数x和函数体都是引用透明的,那么函数f就是纯函数

    不变性(Immutability)

    为了获得引用透明性,任何值都不能变化

    函数式一等公民(First-class Function):

    一切都是计算、函数式编程中只有表达式,变量,函数都是表达式

    即:在程序中用变量的地方都可以使用函数。

    高阶函数(Higher order Function)

    •闭包(Closure)

    表达式求值策略:严格求职 和非严格求职

    (Call By Value vs. Call By Name)

    •惰性求值(Lazy Evaluation):就是说当定义这个表达式的时候不会立即去求值,只有当第一次用到这个表达式的时候才会去求值。

    递归函数(Recursive Function):函数式编程中是没有循环语句的,所有的循环都是用递归来实现。

    •尾递归(Tail Recursion)

    ■函数式编程的优点

    生产效率高

    同样的功能的程序,Lisp代码的长度可能是C代码的1/7~1/10

    易于推理(Reasoning)

    并行编程

    多核计算、云计算

    -------------

    Scala安装

    -------------

    ■JDK:建议Java 7以上)

    下载地址:

    http://www.oracle.com/technetwork/java/javase/downloads/index.html

    http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

    ■Scala 2.11

    下载地址:http://www.scala-lang.org/download/

    ■编译工具SBT

    下载地址:http://www.scala-sbt.org/

    ■交互式程序运行环境REPL(轻量级,用于实验,Read Evaluate Print Loop)

    ■IDE

    下载地址:http://scala-ide.org/

    安装成功之后,在命令行窗口执行以下命令应该可以正确执行(最好重新启动命令行窗口)

    java -version

    scala -version

    -------------

    基础篇

    -------------

    ■变量

    三种变量修饰符

    val 定义immutable variable。也即是常量

    var 定义mutable variable。也就是变量

    lazy val。定义惰性求值的常量

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

    *什么时候我们用lazy val呢?如果我们定义的量,再后续的程序中并不一定会被用到。

    ■数据类型

    *AnyVal:值类型

    *Unit类似Java的void。用Unit标记的函数一般都是有副作用的。

    *Nothing:如果一个函数返回值是Nothing,通常函数是返回异常。

    *String:就是Java的String。不过新增了字符串插值(interpolation)的特性

    val myname = "XXX"

    s"My name is ${myname}"}。就像Shell语言里变量替换一样。

    ■函数与代码块

    •代码块

    代码块用于组织多个表达式,代码块本身也是一个表达式,其最终的求得的值是最后一个表达式的值。

    代码块有一下两种写法。

    {exp1; exp2}

    {

    exp1

    exp2

    }

    •函数

    以关键字def开头。

    返回值可以省略,Scala足够聪明,可以推断返回值类型。

    •if表达式

    和java的if语句是非常类似的。

    *其中红框的表达式的返回结果为空,也就是Unit的文字量,就是那个空括号

    •for comprehension

    for {

    x <- xs   //generator 循环遍历

    y = x + 1 //variable binding 变量绑定

    if (y > 0)  //filter

    } yield y

    例:

    •try 表达式

    和Java中的用法是类似的,但是与Java不同,这里不是一个语句,是一个表达式,会返回一个值。

    *_下划线是一个通配符,它可以通配所有的对象。

    •match 表达式

    与Java中的switch类似。

    *_通配符的那一行,相当于Java中的default,无论是什么类型的值都可以。

    -------------

    求值策略

    -------------

    在Scala里面,所有的计算都是基于表达式的。

    下面是例子

    再看下面的例子

    -------------

    函数

    -------------

    函数是Scala的第一等公民。在Scala中,函数就像普通变量一样,同样也具有函数的类型。

    Scala语言支持

    1、把函数作为实参传递给另外一个函数

    2、把函数作为返回值

    3、把函数赋值给变量

    4、把函数存储在数据结构中

    ■函数类型

    函数类型的格式为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里,匿名函数的定义格式为 (形参列表) => (函数体)

    ■柯里化

    柯里化在函数式编程中是一门非常重要的技术。

    柯里是一位非常著名的数学家,他发明了柯里化这门技术。

    究竟柯里化到底是什么样的概念?

    本质上就是将具有多个参数的函数转换为一条函数列,而每一个节点上是单一参数。

    就是把多个参数单个的拿出来放进括号里面,然后串接起来的一个函数形式。

    例子:

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

    def add(x: Int)(y: Int) = x + y //Scala里柯里化的语法

    ■递归与尾递归

    递归函数(Recursive Function)在函数式编程中是实现循环的一种技术。

    在函数式编程中是没有循环语句这个功能的,所有的循环都是通过递归来进行实现的。

    例子:计算n!(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)

    -------------

    Collecions-list基本使用

    -------------

    ■语言基础

    Collecions集合是一个非常有用的数据结构以及对数据结构的操作。

    scala.collection.immutable

    ■List[T]

    T表示泛型,用于指定List元素的类型。

    *两个冒号::操作符称为"连接操作符"。使用方法:左边是元素,右边是List,会把这个元素添加到List的头部。

    *连接操作符的执行顺序是:从右至左。

    *三个冒号:::也是一种连接操作符。用法同两个冒号一样,用于连接两个List。

    List用法:

    c.head:返回List的第一个元素。

    c.tail:返回头元素之外的所有元素。

    使用isEmpty方法判定是否为空。

    ■List高阶函数

    filter:遍历List,按照指定的条件进行过滤。

    •toList:可以将字符串转换成List。

    •takeWhile:遍历List,直至满足指定的条件。满足条件之后就不会继续遍历了。

    例子:

    ■list中的map高阶函数

    map是对列表中的每一个元素进行映射的高阶函数。它接收的参数就是一个函数。

    如下面的例子

    *flatMap可以将2层List转换为1层。

    ■reduceLeft与flodLeft

    集合的归约操作。就是把集合的元素通过某种运算或者某种操作归约为一个值。

    可以参考这篇博客:http://www.iteblog.com/archives/1228

    ■Range

    是一个整数序列。用to或者until操作符来定义。使用by来定义步长。

    其中:

    1 to 10: 1<= x <= 10

    1 until 10:1 <= x < 10

    ■Stream:

    就是一个lazy List。

    Stream是对程序的性能是有帮助的,因为lazy是当用到的时候才会去求值。

    取得Stream的元素的方法是与List一样的。

    *?表示元素的值还没有确定。

    ■Tuple

    元组。与数据库里的记录的概念非常接近。

    tuple有什么用呢?一般一个函数只能返回一个值,如果需要返回多个值的时候可以使用tuple。

    -----------

    快速排序实例

    -----------

    *:paste进入多行模式,可以进行粘贴。使用ctrl + d退出当前模式。

    阅读材料

    http://docs.scala-lang.org/overviews/collections/introduction.html

  • 相关阅读:
    textArea打印时,内容不显示
    自定义Metadata验证属性
    C# 扩展类与分布类
    JSON基础 JS操作JSON总结
    如何查看别人公众号的粉丝量
    Powerdesigner逆向工程从sql server数据库生成pdm
    springMVC中前台ajax传json数据后台controller接受对象为null
    Mybatis报错: Invalid bound statement (not found)
    Mysql批量插入数据性能问题
    java中String编码转换 UTF-8转GBK
  • 原文地址:https://www.cnblogs.com/quchunhui/p/5331706.html
Copyright © 2011-2022 走看看