《快学Scala》 第1章 基础

一、Scala 解释器

1. 启动解释器的步骤

  • 安装 Scala
  • 确保 Scala /bin 目录位于系统 PATH 中
  • 在操作系统中打开命名行窗口
  • 键入 Scala 并按 Enter 键

详情请参照 Scala开发环境搭建和HelloWorld解析

2. 可以将 Scala 当做工业级的便携计算器使用

这里写图片描述

答案被命名为 res0,你可以在后续操作中使用这个名称,解释器同时还会显示结果的类型。根据启动解释器的方式不同,可能可以使用 Tab 键补全命令/方法名

3. REPL 过程
Scala 解释器读到一个表达式,对它进行求值,将它打印出来,接着再继续下一个表达式。这个过程被称为 读取-求值-打印-循环,即 REPL

从技术上讲,Scala程序并不是一个解释器,实际发生的是,你输入的内容被快速地编译成字节码,然后这段字节码交给由 Java 虚拟机执行。正因为如此,大多数 Scala 程序员更倾向于将它称为 “REPL”

二、声明值和变量

除 了直接使用 res0,res1 等这些名称之外,你自己也可以定义自己的名称

这里写图片描述

我们当然可以在后续表达式中使用这些名称

这里写图片描述

注意:以 val 定义的值实际上是一个常量——无法改变其内容

这里写图片描述

如果要声明其值可变的变量,可以用 var:

这里写图片描述

在 Scala 中,非常鼓励使用 val,大多数程序并不需要那么多 var 变量

注意:不需要给出值或者变量的类型,这个信息可以从你用来初始化它的表达式推断出来(声明值或变量但不做初始化会报错)

这里写图片描述

不过,在必要的时候,也可以指定类型,例如:

这里写图片描述

注意:在 Scala 中,变量或函数的类型总是写在变量或函数名称的后面,这使得我们更容易阅读那些复杂类型的声明

可以将多个值或变量放在一起声明:

《快学Scala》 第1章 基础_第1张图片

在变量声明或赋值语句之后,我们并没有使用分号,(据说在 Scala 中多敲一个字符都嫌烦…)。在 Scala 中,仅当同一行代码中存在多条语句时才需要用分隔开

这里写图片描述

三、常用类型

Scala 有 7 种数值类型: Byte、Char、Short、Int、Long、Float 和 Double,以及一个 Boolean。跟 Java 不同的是,这些类型都是类。Scala 并不刻意区分基本类型和引用类型,可以对数字执行方法,例如:

《快学Scala》 第1章 基础_第2张图片

在 Scala 中,我们不需要包装类型。在基本类型和包装类型之间的转换是 Scala 编译器的工作。举例来说,如果你创建了一个 Int 的数组,最终在虚拟机中得到的是一个 int[] 数组

Scala 用底层的 java.lang.String 类来表示字符串。不过,它通过 StringOps 类给字符串追加了上百种操作。举例来说, interect 方法输出两个字符串共通的一组字符

这里写图片描述

在这个表达式中, java.lang.String 对象“ Hello”被隐式地转换成了一个 StringOps 对象,接着 StringOps 类的 intersect 方法被应用

同样的,Scala 还提供了 RichInt、RichDouble、RichChar等。它们分别提供了 Int、Double、Char等所不具备的便捷方法

前面用到的 to 方法,事实上就是 RichInt 类中的方法,在表达式中

1.to(10)

Int 值 1 首先被转换成 RichInt,然后在应用 to 方法。最后还有 BigInt 和 BigDecimal 类,用于任意大小(但有穷),这些类背后分别对应的是 java.math.BigInteger 和 java.math.BigDecimal

注意:在 Scala 中用方法,而不是强制类型转换,来做数值类型之间的转换。举例来说,99.44.toInt 得到 99 , 99.toChar 得到‘c’, toString 将任意的对象转换成字符串。要将包含了数字的字符串转换成数值,使用 toInttoDouble, 例如, “99.44”.toDouble 得到 99.44

四、算术和操作符重载

Scala 的算术操作符与在 Java 中的预期效果是一样的,区别在于这些操作符实际上是方法,例如

a + b <=> a.+(b)

Scala 可以使用几乎任何符号来为方法命名,Scala 有一个显著的不同, Scala 并没有提供 ++-- 操作符,需要用 += 1-= 1 来代替

counter += 1

但我们无法简单地实现一个名为 ++ 的方法,因为 Int 是不可变的,这样一个方法并不能改变某个整数类型的值。Scala 的设计者们认为不值得为少按一个键额外增加一个特例 -_-!

说明:在 Java 中不能对操作符进行重载,而 Scala 允许定义操作符,由开发者决定是否在必要时有分寸地使用这个特性

五、调用函数和方法

除了方法之外, Scala 还提供函数。相比 Java,在 Scala 中使用数学函数(比如 min 或 pow)更为简,不需要从某个类调用它的静态方法

import scala.math._ // "_" 字符是 "通配符",类似 Java 中的 "*"
sqrt(2)     // 将产生 1.4142...
pow(2,4)    // 将产生 16.0
min(3,Pi)   // 将产生 3.0

Scala 没有静态方法,不过它有个类似的特性,叫做单例对象(singleton object)。通常,一个类对应有一个伴生对象(companion object),其方法就跟 Java 中的静态方法一样,举例:

这里写图片描述

说明:这里的 Random 是一个单例的随机数生成器对象,而该对象是在 Scala .util 包中定义的。这是用单例对象比用类更好的为数不多的场景之一。在 Java 中,为每个随机数都构造出一个新的 Java.util.Random 对象是一个常见的错误

不带参数的 Scala 方法通常不使用圆括号,例如

"Hello".distinct    // 获取字符串中不重复的字符

注意:一般来说,没有参数且不改变当前对象的方法不带圆括号

六、apply 方法

在 Scala 中,通常都会使用类似函数调用的语法,举例来说,如果 s 是一个字符串,那么 s(i) 就是该字符串的第 i 个字符,在 RELP 中运行如下代码:

"Hello"(4) <=> "Hello".apply(4)     // 将产出 "o"

可以将这种用法当做是 () 操作符的重载形式
在 BigInt 伴生对象的文档中,调用

BigInt("1234567890") <=> BigInt.apply("1234567890") 

产出一个新的 BigInt 对象,不需要使用 new。例如:

BigInt("1234567890")*BigInt("112358111321")

像这样使用伴生对象的 apply 方法是 Scala 中构建对象的常用方法,例如, Array(1,4,9,16) 返回一个数组,用的就是 Array 伴生对象的 apply 方法

七、Scaladoc

Scaladoc 的类清单按照包排序,可以在左上角的过滤器上输入所需的类名
注意:每个类名旁边的 O 和 C ,它们分别链接到对应的类 (C) 或伴生对象 (O)

阅读 Scaladoc 可以参照以下几个小窍门

  • 如果想使用数值类型,记得看看 RichInt、RichDouble等。同理,如果想使用字符串,记得看看 SpringOps

  • 那些数学函数位于 scala.math 包中,而不是位于某个类中

  • 有些名称看起来比较奇怪的函数,比如 BigInt 有一个方法叫做 unary_-,这是你定义前置的负操作符 -x 的方式

  • 标记为 implicit 的方法对应的是自动(隐式)转换。比如,BigInt 对象拥有在需要时,自动被调用的由 int 和 long 转换为 BigInt 方法

  • 方法可以以函数作为参数。例如 SpringOpscount 方法需要传入一个接受单个 Char 并返回 true 或 false 的函数,用于指定哪些字符应当被清点:

def count(p:(char) => Boolean) : Int

调用类似方法时,通常可以一种非常紧凑的表示法给出函数定义。例如

s.count(_.isUpper)  // 清点所有大写字母的数量
  • 遇到类似 Range 或 Seq[Char] 这样的类,一个是数字区间,一个是字符序列

  • 当遇到类似 StringOps 类中这样看上去几乎没法一下子理解的方法签名时

    这里写图片描述

    可以直接忽略,还有另一种版本的 patch , 看上去更容易理解

" Harry".patch(1,"ung",2)   // 将产生 "Hungry"

本章知识总结

  • 使用 Scala 解释器
  • 用 var 和 val 定义变量
  • 数字类型
  • 使用操作符和函数
  • 浏览 Scaladoc

快学Scala 第一章 基础 练习请参阅:http://blog.csdn.net/u011414200/article/details/48471939

你可能感兴趣的:(《快学Scala》 第1章 基础)