1 00:00:12,800 --> 00:00:15,080 我们下面来看一下关于 2 00:00:15,080 --> 00:00:17,360 Scala基础的数据类型 变量 3 00:00:17,540 --> 00:00:19,980 输入输出 控制结构以及数据结构 4 00:00:20,180 --> 00:00:22,200 首先来看一下基本的数据类型和变量 5 00:00:23,300 --> 00:00:25,500 我们会给大家介绍关于基本数据类型 6 00:00:25,500 --> 00:00:27,340 以及一些基本操作和变量 7 00:00:28,760 --> 00:00:30,580 对于基本的数据类型 8 00:00:30,580 --> 00:00:33,340 Scala数据类型跟Java还是比较类似的 9 00:00:33,720 --> 00:00:36,600 也能看到Byte类型 Char类型 Short类型 10 00:00:36,600 --> 00:00:39,220 Int类型 Long Float Double Boolean等等 11 00:00:40,100 --> 00:00:42,460 那么和Java不一样的地方是什么呢 12 00:00:42,560 --> 00:00:45,140 要注意 我们在整个Scala当中 13 00:00:45,140 --> 00:00:47,640 我们所定义的这些类型都是类 14 00:00:47,820 --> 00:00:49,260 比如说 Int类型 15 00:00:49,360 --> 00:00:52,700 实际上它是一个scala.Int类 16 00:00:53,300 --> 00:00:55,140 然后有一个比较特殊的地方 17 00:00:55,680 --> 00:00:59,160 整个Scala当中String类型没有自己的定义 18 00:00:59,840 --> 00:01:03,300 它是完全直接从Java当中照搬过来的 19 00:01:03,500 --> 00:01:05,860 所以它用的是java.lang.String这个类 20 00:01:05,940 --> 00:01:08,340 来表示字符串 这个地方要注意 21 00:01:08,940 --> 00:01:13,300 这个表给出了每一种数据类型的取值范围 22 00:01:13,880 --> 00:01:15,300 这个大家看一下就知道了 23 00:01:18,680 --> 00:01:20,100 第二个概念大家要注意 24 00:01:20,280 --> 00:01:21,860 有一个字面量的概念 25 00:01:22,580 --> 00:01:24,880 为什么讲字面量呢 因为后面会给大家讲 26 00:01:24,880 --> 00:01:26,580 相关的函数式编程的时候 27 00:01:26,580 --> 00:01:27,440 也会提到这个事情 28 00:01:27,440 --> 00:01:29,060 所以要先知道什么是字面量 29 00:01:29,760 --> 00:01:31,040 所谓的字面量 30 00:01:31,100 --> 00:01:32,540 我们给大家举一个实例就知道了 31 00:01:32,940 --> 00:01:36,080 比如说我们先定义一个val i=123 32 00:01:36,240 --> 00:01:38,840 这个123就是一个整型的字面量 33 00:01:39,720 --> 00:01:42,820 val i=3.14 3.14是一个浮点型字面量 34 00:01:43,440 --> 00:01:44,640 然后val i=true 35 00:01:44,640 --> 00:01:46,240 这个true是布尔型字面量 36 00:01:46,360 --> 00:01:48,920 然后val i=’A’ 37 00:01:49,440 --> 00:01:51,680 这个’A’就是一个字符的字面量 38 00:01:52,220 --> 00:01:53,500 这些都叫字面量 39 00:01:53,980 --> 00:01:56,360 然后 我们后面讲到函数式编程的时候 40 00:01:56,360 --> 00:01:58,220 还会给大家介绍函数的字面量 41 00:01:59,160 --> 00:02:00,260 第三 我们看一下操作符 42 00:02:01,000 --> 00:02:03,340 操作符也是大家在编程的时候经常用到的 43 00:02:03,500 --> 00:02:05,000 而且都是比较类似的 44 00:02:05,140 --> 00:02:08,060 Scala也是有算术运算符 关系运算符 45 00:02:08,060 --> 00:02:10,980 逻辑运算符 位运算符和赋值运算符 46 00:02:11,340 --> 00:02:12,900 这个我们不会讲得太详细 47 00:02:12,900 --> 00:02:15,220 因为我们以前都学过这些相关的操作 48 00:02:16,020 --> 00:02:17,600 算术运算符加减乘除 49 00:02:18,160 --> 00:02:20,060 关系运算符 大于 小于 大于 等于 50 00:02:20,500 --> 00:02:23,360 逻辑运算符 逻辑与 或 非等等 51 00:02:23,880 --> 00:02:26,240 优先级跟Java也是类似的 52 00:02:26,420 --> 00:02:30,240 比如说 算数运算符优先级高于关系运算符 53 00:02:30,240 --> 00:02:33,080 高于逻辑运算符 高于赋值运算符 54 00:02:33,460 --> 00:02:35,560 这些都是我们以前学习编程语言的时候 55 00:02:35,760 --> 00:02:37,340 非常熟悉的 就不细讲了 56 00:02:40,840 --> 00:02:44,060 比较特殊的 在之前也给大家提到过 57 00:02:44,060 --> 00:02:48,360 在Scala当中 我们每一个操作符实际上 58 00:02:48,360 --> 00:02:50,540 就是已经被定义成了一个方法 59 00:02:51,480 --> 00:02:53,280 什么意思呢 就比如说5+3 60 00:02:53,500 --> 00:02:55,940 5+3要注意 实际上调用的是什么 61 00:02:55,940 --> 00:02:58,840 调用的是5这个对象它有个加的方法 62 00:02:58,840 --> 00:03:01,500 然后把3作为一个参数 63 00:03:01,500 --> 00:03:03,600 传递给这个加方法 64 00:03:04,020 --> 00:03:06,360 它会帮你算出来5+3等于8 65 00:03:06,780 --> 00:03:09,680 所以要注意 这里面有一个通用的表达方式 66 00:03:09,900 --> 00:03:15,700 a 方法 b 就等价于a.方法(b) 67 00:03:16,080 --> 00:03:19,320 它们是等价的 所以是5+3等价5.+(3) 68 00:03:19,980 --> 00:03:23,880 所以要注意 面向对象的Scala编程里面 69 00:03:24,020 --> 00:03:25,480 每一个值都是一个对象 70 00:03:25,480 --> 00:03:27,660 每一个操作符都是对象的方法 71 00:03:28,560 --> 00:03:30,840 如果在Scala的提示符下面 72 00:03:30,840 --> 00:03:33,900 去执行这么两条语句 它是完全一样的结果 73 00:03:33,900 --> 00:03:36,160 比如val sum1=5+3 74 00:03:36,420 --> 00:03:39,240 它实际上和val sum2=(5).+(3) 75 00:03:39,240 --> 00:03:40,700 得到的结果是一样的 都是8 76 00:03:41,240 --> 00:03:43,160 再看一下关于富包装类 77 00:03:43,360 --> 00:03:44,400 要补充一下这个问题 78 00:03:44,480 --> 00:03:47,700 就是说 对于一些数据类型 79 00:03:47,700 --> 00:03:49,840 每一种数据类型都定义了一些 80 00:03:49,840 --> 00:03:51,080 基本的操作方法 81 00:03:51,260 --> 00:03:55,980 比如说整型有加减乘除 这些基本的方法 82 00:03:56,840 --> 00:03:59,640 但是要注意 有些相关的方法 83 00:03:59,660 --> 00:04:02,600 它是不会被定义到基本类当中去的 84 00:04:02,980 --> 00:04:05,660 scala.Int这么一个类里面 85 00:04:06,080 --> 00:04:08,380 它可能就定义了加减乘除这些基本的操作 86 00:04:08,900 --> 00:04:11,540 然后它没有可以定义一些比较复杂的 87 00:04:12,280 --> 00:04:14,380 或者说有一些数学上的一些操作 88 00:04:14,860 --> 00:04:18,460 比如求最大值的这个max这个方法 89 00:04:18,460 --> 00:04:20,400 它就没有定义 这种操作它是没有定义的 90 00:04:21,200 --> 00:04:23,560 那我们有时候又是可以去用这个max的 91 00:04:24,240 --> 00:04:27,280 比如说我们想用3 max 5看看两个值谁大 92 00:04:27,480 --> 00:04:29,820 它会告诉你结果是5 因为5比较大 93 00:04:30,680 --> 00:04:32,960 那你会发现 那为什么它又可以这么去做呢 94 00:04:32,960 --> 00:04:35,520 既然基本类中没有这么一个max方法 95 00:04:35,520 --> 00:04:37,740 它为什么又可以去用这个max方法呢 96 00:04:38,560 --> 00:04:42,100 就是因为对于每一个基本类来讲 97 00:04:42,320 --> 00:04:45,580 它有一个专门的相对应的富包装类 98 00:04:46,020 --> 00:04:49,220 这个富包装类是以Rich开头的 99 00:04:49,220 --> 00:04:50,960 把它翻译成富包装类 100 00:04:51,240 --> 00:04:54,260 所以 像这个整型它就有一个 101 00:04:54,700 --> 00:04:57,300 RichInt 是它所对应的富包装类 102 00:04:57,620 --> 00:04:59,920 如果是String的话 它有一个RichString 103 00:05:00,280 --> 00:05:01,660 是它所对应的富包装类 104 00:05:01,900 --> 00:05:02,420 也就是说 105 00:05:02,620 --> 00:05:04,880 我们有时候可能用得到的一些方法 106 00:05:05,000 --> 00:05:08,120 它都会被定义到富包装类里面去 107 00:05:09,280 --> 00:05:11,740 这样 一旦我们用到了这种方法 108 00:05:12,640 --> 00:05:16,400 它会隐式地并且是自动地帮我们 109 00:05:16,400 --> 00:05:19,880 把当前这个对象转换成富包装类 110 00:05:19,880 --> 00:05:23,240 所对应的对象 原来说的3是Int类型 111 00:05:23,940 --> 00:05:27,700 5是Int类型对象 然后3 max 5 112 00:05:27,980 --> 00:05:29,580 一执行这种操作以后你会发现 113 00:05:29,880 --> 00:05:32,760 这个max不属于这个Int类型的方法 114 00:05:33,420 --> 00:05:36,620 所以它会自动地 隐式地 115 00:05:36,620 --> 00:05:39,620 把这个3从一个Int类型的对象 116 00:05:39,860 --> 00:05:43,360 自动隐式转换成为一个RichInt类型对象 117 00:05:43,640 --> 00:05:45,400 RichInt类型对象里面 118 00:05:45,400 --> 00:05:47,160 就已经定义了max方法 119 00:05:47,440 --> 00:05:49,540 所以 它自己就可以得到结果 120 00:05:49,800 --> 00:05:51,240 这叫富包装类 121 00:05:53,380 --> 00:05:54,040 再看变量 122 00:05:54,700 --> 00:05:56,600 变量是我们在写Scala代码当中 123 00:05:56,660 --> 00:05:57,700 经常会用得到的 124 00:05:57,920 --> 00:06:00,560 在Scala当中有两种类型的变量 125 00:06:01,240 --> 00:06:02,640 第一种是不可变的变量 126 00:06:02,820 --> 00:06:04,060 第二种是可变的变量 127 00:06:04,060 --> 00:06:05,520 对于函数式编程来讲 128 00:06:05,520 --> 00:06:07,140 一般都是用不可变的变量 129 00:06:07,680 --> 00:06:09,320 而对于面向对象编程而言 130 00:06:09,320 --> 00:06:10,600 可能用这个可变的变量 131 00:06:10,600 --> 00:06:11,920 因为我们面向对象用习惯了 132 00:06:12,440 --> 00:06:15,800 定义一个变量 我们会想把它直接进行变更 133 00:06:16,700 --> 00:06:18,280 但是对于函数式编程来讲 134 00:06:18,500 --> 00:06:19,920 变量定义好以后是不能变的 135 00:06:20,380 --> 00:06:23,760 所以说它是融合了两种不同的编程风格 136 00:06:24,460 --> 00:06:26,780 变量也分了两种不同的类型 137 00:06:27,300 --> 00:06:30,520 第一个是value类型叫val 138 00:06:30,520 --> 00:06:33,120 第二种是variable可变 叫var类型 139 00:06:33,120 --> 00:06:35,120 我们可以这么发音 140 00:06:35,420 --> 00:06:38,420 val类型是不可变的 141 00:06:38,860 --> 00:06:40,440 那对于这种不可变的变量 142 00:06:40,720 --> 00:06:43,040 我们在声明的时候就必须给它初始化 143 00:06:43,260 --> 00:06:44,200 因为它是不可变的 144 00:06:44,200 --> 00:06:46,280 一旦声明了并且给它赋值了 145 00:06:46,640 --> 00:06:49,060 后面就不能对它再进行变更 146 00:06:50,440 --> 00:06:51,640 而对于var类型呢 147 00:06:52,380 --> 00:06:54,960 声明的时候需要进行初始化 148 00:06:54,960 --> 00:06:58,760 后面可以对它再次进行赋值 这是可以的 149 00:07:00,040 --> 00:07:02,160 所以要注意 有两种不同类型变量 150 00:07:02,660 --> 00:07:05,020 声明的方式很简单 151 00:07:05,620 --> 00:07:07,260 如果是不可变的 那么就是 152 00:07:07,260 --> 00:07:10,880 val 变量名:数据类型等于初始值 153 00:07:11,760 --> 00:07:16,120 比如说val a:Int=3 154 00:07:16,200 --> 00:07:19,080 就是声明一个整型 初始值是3 155 00:07:19,500 --> 00:07:21,460 同理 var类型也是一样的 156 00:07:21,520 --> 00:07:23,940 也是var变量名:数据类型=初始值 157 00:07:24,340 --> 00:07:25,820 这是它的一个规范格式 158 00:07:27,360 --> 00:07:29,440 在Scala当中有一种非常好的机制 159 00:07:29,540 --> 00:07:31,840 叫类型的自动推断机制 160 00:07:32,440 --> 00:07:33,840 当我们写代码的时候很省事 161 00:07:34,300 --> 00:07:37,100 我们没有必要每次在声明的时候 162 00:07:37,100 --> 00:07:39,840 都给出这个变量它属于某种类型 没有必要 163 00:07:40,740 --> 00:07:42,280 系统是可以帮你自动推断的 164 00:07:42,500 --> 00:07:43,520 看这一行代码 165 00:07:44,120 --> 00:07:46,820 val myStr="Hello World!"很显然 166 00:07:47,100 --> 00:07:49,160 val myStr后面没有跟上冒号 167 00:07:49,160 --> 00:07:52,180 属于String类型 但是回车以后会发现 168 00:07:52,420 --> 00:07:53,760 系统会自动发现 169 00:07:53,760 --> 00:07:56,400 myStr:String="Hello World!" 170 00:07:56,800 --> 00:07:59,440 从返回的信息当中 你能够发现 171 00:07:59,440 --> 00:08:02,300 系统已经自动地把它解析为String类型 172 00:08:03,240 --> 00:08:06,040 如果你不放心 想显式声明 也是可以的 173 00:08:06,040 --> 00:08:08,360 如果不想让它自动推断 就可以显式声明 174 00:08:08,360 --> 00:08:11,720 使用val myStr2:String="Hello World!" 175 00:08:11,720 --> 00:08:12,540 这也是可以的 176 00:08:13,260 --> 00:08:14,800 然后 println(myStr) 177 00:08:14,800 --> 00:08:16,040 就可以打印出来“Hello World!” 178 00:08:16,860 --> 00:08:20,500 这个是变量的声明方式 我们说过 179 00:08:20,700 --> 00:08:22,860 只要声明了val类型的变量 180 00:08:22,860 --> 00:08:25,780 后面不能再对它进行赋值了 比如说这里 181 00:08:26,040 --> 00:08:27,060 下面会报错 182 00:08:27,660 --> 00:08:29,860 myStr="Hello Scala!" 183 00:08:30,140 --> 00:08:31,860 这时候已经给它赋了一个初值 184 00:08:32,460 --> 00:08:33,940 我们在上面这一行已经 185 00:08:33,940 --> 00:08:35,360 val myStr="Hello World!" 186 00:08:35,360 --> 00:08:36,500 这个时候又想变更 187 00:08:36,500 --> 00:08:38,500 让myStr="Hello Scala!" 188 00:08:38,620 --> 00:08:41,640 想对它进行二次的赋值 它马上会报错 189 00:08:41,660 --> 00:08:45,120 告诉你error:reassignment to val 190 00:08:45,120 --> 00:08:46,260 告诉你这是错的 191 00:08:46,820 --> 00:08:49,340 不能再对它进行重新赋值 192 00:08:49,340 --> 00:08:51,620 因为它是一个val类型的变量 是不可变的 193 00:08:53,020 --> 00:08:54,440 那var类型变量呢 194 00:08:55,140 --> 00:08:58,060 很显然 你赋值一次 后面可以不断地变更 195 00:08:58,500 --> 00:09:00,480 比如说价格 它可以不断变化 196 00:09:00,480 --> 00:09:04,260 所以var myPrice:Double=9.9 197 00:09:04,500 --> 00:09:06,160 后面又定义了myPrice=10.6 198 00:09:06,160 --> 00:09:07,960 这是可以的 因为它是var类型 199 00:09:09,580 --> 00:09:11,220 然后还有一个地方要注意 200 00:09:11,320 --> 00:09:12,040 这里有一个实例 201 00:09:12,280 --> 00:09:15,460 你开始val a="Xiamen University" 202 00:09:16,160 --> 00:09:17,760 这个时候a是字符串类型的 203 00:09:18,020 --> 00:09:19,700 然后又声明var a=50 a 204 00:09:19,700 --> 00:09:20,960 又变成一个整型 205 00:09:21,340 --> 00:09:23,920 也就是说 在同样一个执行环境当中 206 00:09:24,120 --> 00:09:26,880 可以不断地重复使用同样一个变量名 207 00:09:26,880 --> 00:09:29,380 它会记住你最后一次用的那个类型