简介:Scala-升级版.docx 面向大数据开发初学者与 Spark 学习者,是一份从环境搭建讲到面向对象编程的 Scala 入门笔记。内容围绕 Scala 运行于 JVM、融合面向对象与函数式编程的特点展开,梳理了 Java 互操作、类型推测、并发与分布式、特质、模式匹配、高阶函数六大特征,并说明 Spark 1.6 依赖 Scala 2.10、Spark 2.0 起改用 2.11 的版本对应关系。实操层面涵盖 Windows 与 Linux 下的安装及环境变量配置,以及 IDEA 中 Scala 插件的安装与 SDK 设置;语法层面涉及 var/val 变量与常量、条件表达式、类与单例对象、apply 方法与伴生对象等基础知识点,并附有可直接运行的示例代码。压缩包内含 1 个 docx 文件,约 2.04MB,结构紧凑,便于随手查阅。目前已有 2066 人学习下载,适合作为入门提纲与课堂笔记的补充。
1. 装 Scala 之前,先把 JDK 1.8 钉死
上周帮一位开发者收拾一台开发机,IDEA 里 Scala 插件显示装好了,新建项目也能建,但一敲scala -version就报「不是内部或外部命令」。查了半天,是机器上原来有一套 JDK 11,Scala 2.11.8 的启动脚本读不到对应的运行时,环境变量又指向了另一个目录。这类翻车在 Scala 环境搭建里太常见了:Scala 跑在 JVM 上,JDK 版本、SCALA_HOME、Path 三者只要有一个对不上,表现就是各种莫名其妙的启动失败。
Scala 在大数据方向几乎是绕不开的语言,Spark 1.6 用的是 Scala 2.10,Spark 2.0 往上换成 Scala 2.11,版本对不上,依赖一编译就炸。所以这篇按「装什么版本 → Windows 和 Linux 怎么装 → IDEA 怎么配 → 基础语法怎么验证环境真的通了」的顺序走一遍,新手能照着装完,熟手能看清版本取舍和几个血泪坑。
2. 版本选型与安装包准备:JDK、Scala、IDEA 三者怎么配
装 Scala 之前最该做的一件事不是下载,而是把版本关系理清楚。Scala 是 JVM 语言,编译出来的字节码要靠 JDK 跑;IDEA 是编辑器,它自己也需要 JDK,同时还要加载 Scala 插件和 Scala SDK。这三者的版本是一条链,任何一环错位都会在某个环节报错,而且报错信息往往指向的不是真正的原因。
2.1 JDK 版本:为什么推荐 1.8 而不是更高
Scala 2.11.x 这一代编译器和运行时是按 JDK 8 验证得最充分的,社区里大量 Spark 相关工程也是锁在 JDK 8 上。常见做法是直接装 JDK 1.8,不要图新装 11 或 17——不是说绝对跑不起来,而是你会遇到一类很难定位的问题:Scala 启动脚本能跑,但某些反射、字节码版本相关的操作在运行时抛异常,日志里看不出跟 JDK 有关系。
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| JDK | 1.8(8u 系列) | 与 Scala 2.11.x 配套最稳,Spark 生态常用 |
| Scala | 2.11.8 | 与 Spark 2.0+ 对齐,Windows 有 msi 安装包 |
| IDEA | 与 Scala 插件兼容的版本 | 插件必须匹配 IDE 大版本,不能随便下 |
| Scala 插件 | 与 IDEA 版本对应 | 在 IDEA 插件市场内搜索安装,不要手动拷 jar |
装完 JDK 后先验证,别急着往下走:
# 确认 JDK 版本与安装路径,后面配置 IDEA 的 Project SDK 要用到 java -version # 期望输出类似:java version "1.8.0_xxx" # 打印 JAVA_HOME,确认环境变量指向的是 1.8 的安装目录 echo %JAVA_HOME% # Windows cmd echo $JAVA_HOME # Linux / macOSjava -version看的是 Path 里第一个 java 可执行文件,JAVA_HOME看的是变量值,两者可能不是同一套 JDK,这是很多「明明装了 1.8 却还是报错」的根源。我一般会要求这两个输出指向同一个目录,再继续下一步。
2.2 Scala 版本:2.11.8 与 2.10 的取舍
原文明确提到 Spark 1.6 对应 Scala 2.10,Spark 2.0 以上对应 Scala 2.11。如果你学 Scala 是为了后面写 Spark 作业,那版本应该跟着你目标环境的 Spark 走,而不是跟着「最新版」走。Windows 下官方提供scala-2.11.8.msi,双击安装即可,安装程序会自动处理一部分环境变量;Linux 下更简单,下载二进制压缩包解压后配 PATH 就能用。
需要提醒的是,Scala 2.11 和 2.12、2.13 在集合库上有较大差异,2.13 甚至重写了集合框架。学习阶段用 2.11.8 没问题,但如果你后续要接的项目是 2.12 以上,注意语法示例里的一些写法(尤其是集合相关)可能需要调整。这也是为什么我不建议一上来就装最新版:教程、Spark 版本、第三方库三者会同时给你制造麻烦。
2.3 IDEA 与 Scala 插件的匹配关系
IDEA 的 Scala 插件是随 IDE 版本走的,插件市场里能搜到的版本一定对应你当前 IDE 的大版本号。原文里提到「下载插件一定要对应 eclipse 版本下载」,这个道理在 IDEA 上同样成立,只是 IDEA 通过插件市场自动帮你做了匹配,省掉了手动找版本这一步。
至于 Eclipse 那条路,原文写得很直白:不建议。原因是 Eclipse 的 Scala 插件需要手动把 features 和 plugins 两个文件夹拷到dropins/scala目录下,版本对不上就是一片红叉,排错成本远高于收益。Scala IDE 是另一条路,本质是打包好的 Eclipse,能用,但生态和维护活跃度都不如 IDEA。学习阶段直接用 IDEA,是把时间花在语言本身而不是工具链上的做法。
3. Windows 与 Linux 安装 Scala:环境变量三个路径别写错
这一章是实际动手部分。Windows 走 msi,Linux 走解压,两条路的验证方式一样,但踩的坑不一样。
3.1 Windows 下用 msi 安装并核对环境变量
双击scala-2.11.8.msi一路下一步即可。安装程序通常会自动创建SCALA_HOME并把 bin 目录加进 Path,但「通常」不等于「一定」,装完必须自己核对一遍。
第一步,确认安装目录,默认一般在C:\Program Files (x86)\scala。然后打开系统环境变量,检查是否存在SCALA_HOME:
# 在 cmd 中查看,确认 SCALA_HOME 指向 Scala 安装根目录(不是 bin 目录) echo %SCALA_HOME% # 期望输出类似:C:\Program Files (x86)\scala第二步,编辑 Path,确认里面包含下面两段(注意是追加,不要覆盖原有内容):
;%SCALA_HOME%\bin;%SCALA_HOME%\jre\bin这里有两个容易写错的地方。一是SCALA_HOME要指向安装根目录,不能带\bin,否则拼出来的路径会变成...\scala\bin\bin。二是jre\bin这一段别漏,Scala 安装包自带一个精简 JRE,某些情况下启动脚本会用到它;漏了这段,scala命令可能能起来但行为异常。
第三步,验证。必须新开一个 cmd 窗口,已经打开的窗口读不到新加的环境变量:
# 输出 Scala 版本号即表示安装成功 scala -version # 期望输出类似:Scala code runner version 2.11.8如果这条命令报「不是内部或外部命令」,按顺序排查:Path 里有没有%SCALA_HOME%\bin、SCALA_HOME是否指向了带 bin 的路径、当前窗口是不是新开的。这三条覆盖了九成的失败情况。
3.2 Linux 下解压安装与 PATH 配置
Linux 下不需要安装程序,下载scala-2.11.8.tgz解压到某个目录,然后把它加进 PATH 即可。
# 解压到 /opt 下,目录名保持和版本对应,方便以后共存多个版本 tar -zxvf scala-2.11.8.tgz -C /opt/ # 验证解压结果,bin 目录下应该有 scala 和 scalac ls /opt/scala-2.11.8/bin接着配置环境变量。写到~/.bashrc里对当前用户生效,写到/etc/profile里对全局生效,学习机上两种都行:
# 追加到 ~/.bashrc 末尾 export SCALA_HOME=/opt/scala-2.11.8 export PATH=$SCALA_HOME/bin:$PATH # 让配置立即生效 source ~/.bashrc注意PATH的拼接顺序,$SCALA_HOME/bin放在前面,能保证你敲scala时优先用到这一套。如果机器上之前装过别的版本,which scala可以确认最终命中的是哪个可执行文件,这个命令在排查多版本冲突时很好用。
验证方式与 Windows 一致:
scala -version3.3 用交互式 REPL 做第一次运行验证
版本号能打印出来,只说明命令找到了,不代表运行时没问题。真正的验证是进入 REPL 敲几行代码,因为 REPL 会启动完整的编译和执行链路。
# 进入 Scala 交互式环境 scala进入后依次输入:
// 变量与常量:var 可重新赋值,val 不可 var name = "zhangsan" name = "lisi" val gender = "m" // gender = "f" // 这一行会编译报错,val 不可重新赋值 // 表达式赋值,Scala 的 if 是有返回值的 val x = 1 val y = if (x > 0) 1 else -1 println(y) // 输出 1val等价于 Java 里的 final,var才是可变的,这是 Scala 极简原则的体现:能不变就不变。如果你敲完gender = "f"没有报错,说明你用的可能不是 Scala,或者敲错了变量名,值得停下来确认一下。
再敲一段带对象和方法的代码,验证编译链路:
// class 定义类,object 是单例对象,相当于 Java 里的工具类 class Person { val name = "zhangsan" val age = 18 def sayName() = "my name is " + name } object Demo { def main(args: Array[String]): Unit = { val p = new Person() println(p.age) println(p.sayName()) } }REPL 里也可以直接new Person()然后调方法,不用写 main。这一步过了,说明 JDK、Scala 运行时、编译器三件套是通的,可以进 IDE 了。
4. IDEA 里配置 Scala 插件与 SDK:新建项目跑通第一段代码
命令行的 Scala 能跑,说明环境层没问题了。接下来把开发环境搬到 IDEA,这一步的坑比装 Scala 本身还多。
4.1 安装 Scala 插件并重启
打开 IDEA,先关掉当前项目(Close Project),回到欢迎界面,点Configure→Plugins,在搜索框里输入 scala,找到 Scala 插件点 Install,装完必须重启 IDE。不重启的话插件不会加载,新建项目时看不到 Scala 选项。
这里有个细节:插件市场会根据你的 IDE 版本只展示兼容的插件版本,所以不要从外部网站下 jar 包手动装,版本对不上会直接导致 IDE 启动异常,退回都麻烦。原文里特别强调插件要对应版本下载,原因就是这个。
4.2 配置 Project SDK 与 Scala SDK
插件装好后还有两件事要配,很多人只配了一件就卡住。
第一件是 Project SDK,也就是 JDK。打开File→Project Structure,在Project页里点New,选择你装好的 JDK 1.8 路径。这一步决定 IDEA 编译时用哪个 JDK。
第二件是 Scala SDK。新建 Scala 项目时,在项目配置里找到 Scala SDK 一栏,点Create或Browse,选择本地 Scala 安装目录(比如C:\Program Files (x86)\scala)。IDEA 会扫描这个目录下的 jar 并注册为一个 SDK。注意选的是 Scala 安装根目录,不是 bin 目录,也不是 jre 目录,选错了会提示找不到 SDK。
配置完成后,新建一个 Scala 项目,目录结构大致如下:
my-scala-demo/ ├── src/ │ └── main/ │ └── scala/ │ └── Demo.scala └── pom.xml 或 build.sbt # 看项目类型如果新建项目时没有使用构建工具,就是一个普通 Scala 项目,直接在src下建 Scala 文件即可。第一次建文件时,IDEA 可能会提示「Scala SDK is not defined」,回到 Project Structure 里补上就行。
4.3 第一个可运行程序与运行配置
在src下新建Demo.scala,内容如下:
// object 是单例对象,main 方法是程序入口 object Demo { def main(args: Array[String]): Unit = { // 循环:1 to 10 包含 10,1 until 10 不包含 10 for (i <- 1 to 10) { print(i + " ") } println() // 带条件的 for,取值后通过 yield 生成新集合 val evens = for (i <- 1 to 100 if i > 50 if i % 2 == 0) yield i println(evens) } }右键文件,选择Run 'Demo'。如果控制台打印出 1 到 10 和 50 到 100 之间的偶数集合,说明整条链路打通了:IDEA → Scala 插件 → JDK → Scala SDK → 编译器 → 运行时。
yield是 Scala 里很好用的一个点,它把满足条件的元素收集成一个集合返回,等价于「过滤 + 映射」的组合。原文在 for 循环部分专门提到这一点,实际写 Spark 作业时这种写法用得非常多。
运行配置如果没自动生成,可以点右上角运行配置的下拉框,选Edit Configurations,新增一个 Application 类型,Main class 填Demo,Module 选当前模块即可。
5. 语法自检清单:用一段代码验证环境真的通了
环境配好之后,我习惯跑一段覆盖主要语法点的代码,一次性验证变量、方法、函数、高阶函数、模式匹配这些能力都能正常工作。这比逐个试要快,也方便以后换机器时做回归。
5.1 覆盖变量、方法、函数的自检脚本
object SelfCheck { // 方法:带参数、带返回值,返回值类型可省略(递归时必须写) def add(a: Int, b: Int): Int = a + b // 递归方法,求阶乘,返回值类型不能省 def factorial(n: Int): Int = { if (n == 1) n else n * factorial(n - 1) } // 默认参数:调用时未传的参数用默认值 def greet(name: String = "scala"): String = "hello, " + name // 可变参数 def sum(nums: Int*): Int = nums.sum def main(args: Array[String]): Unit = { println(add(1, 2)) // 3 println(factorial(5)) // 120 println(greet()) // hello, scala println(greet("idea")) // hello, idea println(sum(1, 2, 3, 4)) // 10 // 函数是一等公民,可以赋给变量、作为参数传递 val f = (x: Int, y: Int) => x * y println(f(3, 5)) // 15 // 高阶函数:参数是函数 def applyTwice(fn: Int => Int, x: Int): Int = fn(fn(x)) println(applyTwice(_ + 1, 5)) // 7 } }这段代码里每一块都对应环境验证的一个能力点:add验证方法定义和类型推断,factorial验证递归(返回值类型省略会编译失败,这也是原文强调的必须写返回类型的场景),greet验证默认参数,sum验证可变参数,f验证函数字面量,applyTwice验证高阶函数。如果全部输出正确,说明编译器、标准库、运行时都是好的。
一个常见的误用是把它写成方法而不是函数然后困惑为什么不能传参:def f(x: Int) = x * 2是方法,val f = (x: Int) => x * 2是函数。方法可以自动转换成函数,但在需要函数值的地方,显式写函数字面量更清楚。
5.2 用报错反推环境问题
有时候代码跑不起来,报错信息本身就能告诉你环境哪里不对。下面这张表是我从踩坑记录里整理的对照关系:
| 现象 | 大概率原因 | 处理方式 |
|---|---|---|
scala: command not found | Path 没配或没生效 | 检查 SCALA_HOME 与 Path,新开终端 |
| IDEA 提示找不到 Scala SDK | SDK 指到了 bin 或 jre 目录 | 重新指向 Scala 安装根目录 |
编译报bad option: -make | IDEA 与 Scala 插件版本不匹配 | 升级或降级插件到匹配版本 |
Unsupported class file major version | JDK 版本与 Scala 版本不匹配 | 统一换成 JDK 1.8 |
| REPL 能跑但项目报错 | Project SDK 与 global SDK 不一致 | 检查 Project Structure 两级配置 |
最后一行那个问题特别隐蔽:IDEA 里有「全局 SDK」和「项目 SDK」两层,只配了全局的,项目仍可能用默认值。我一般会在项目建好后进 Project Structure 再确认一次,两处都指向同一个 JDK 1.8。
6. 避坑与排查:五个真实踩过的坑
6.1 装完 scala 敲命令提示不是内部或外部命令
现象:msi 装完,环境变量看着也加了,cmd 里敲scala -version报「不是内部或外部命令」。
原因:八成是 cmd 窗口在装之前就打开了,进程环境变量是快照,读不到新值。剩下一成是 Path 里拼成了...\scala\bin\bin。
解决:关掉所有 cmd 窗口重新开一个;再不行就echo %PATH%看里面实际拼出来的是什么,路径错了回环境变量里改。
6.2 IDEA 插件装好了,新建项目还是没有 Scala 选项
现象:插件市场显示已安装,重启过 IDE,New Project 里仍没有 Scala。
原因:装的是别的 IDE 的插件市场入口,或者装完没真正重启;也可能 IDE 版本太新而插件还没跟上。
解决:确认Configure→Plugins里 Scala 状态是 Enabled,不是只 Installed;再 File → Invalidate Caches 清一次缓存重启。还不行就换一个与插件兼容的 IDEA 版本,别硬扛。
6.3 项目能编译,运行时报找不到主类
现象:代码没红,Run 的时候报Could not find or load main class。
原因:运行配置里的 Module 没选对,或者 main 方法写在 class 里而不是 object 里。Scala 的 main 必须放在 object 里,放在 class 里编译得过但跑不起来。
解决:检查运行配置的 Main class 和 Module;确认入口是object Xxx { def main(args: Array[String]): Unit = ... }。
6.4 环境变量配了,但java -version和scala -version用的不是同一套 JDK
现象:两个命令都能跑,但版本对不上,或者换机器后行为不一致。
原因:JAVA_HOME和 Path 里的 java 不是同一个目录,Scala 启动脚本读JAVA_HOME,而java命令走 Path。
解决:where java(Windows)或which java(Linux)查实际命中的路径,把它和JAVA_HOME统一。这一步花两分钟,能省掉后面几小时的玄学排查。
6.5 val 重新赋值报错,以为是环境问题
现象:照着教程敲val声明的变量又赋了一次值,编译报错,怀疑环境坏了。
原因:val是不可变常量,等价于 Java 的 final,这是语言设计不是环境问题。
解决:需要可变就用var。Scala 提倡尽量用val,极简原则下「不用写的东西一概不写」,但「不能改的东西别改成能改」也是同一套思路的另一面。
7. 装完怎么验证跑通:一次完整的端到端检查
最后说说我怎么确认一套 Scala 环境是「真的能用」而不是「看起来能用」。很多人的验证止步于scala -version,这只能证明命令存在,证明不了编译、运行、IDE 集成这三条链路都通。我的做法是走一遍四层检查,任何一层失败都能定位到具体环节。
第一层,命令行版本与 JDK 一致性:
scala -version javac -version java -version三个输出里的版本号要能对上:Scala 2.11.8 配 JDK 1.8。如果javac和java版本不一致,说明机器上有多套 JDK,Path 没排好序。
第二层,REPL 交互验证:
val list = for (i <- 1 to 10 if i % 2 == 0) yield i println(list) // Vector(2, 4, 6, 8, 10) def square(x: Int) = x * x println(list.map(square))REPL 能出结果,说明编译器、标准库、运行时都在位。注意yield返回的是集合,不是打印,这一点和环境无关但初学者常弄混。
第三层,IDEA 项目端到端:新建一个 Scala 项目,写一个带object+main+ 类 + 方法的文件,右键 Run,控制台有输出。
第四层,外部依赖验证(可选但推荐):如果你的目标是用 Spark,可以在build.sbt或pom.xml里加一个 Scala 2.11 对应的依赖,看 IDEA 能否正常解析。能解析下载,说明网络和仓库配置也没问题;这一步失败了不一定是 Scala 环境的问题,但能提前暴露构建工具链的坑。
四层都过,这套环境我就敢交付了。表格再压缩一遍,方便你对照:
| 检查层 | 命令或动作 | 通过标准 |
|---|---|---|
| 命令行 | scala -version | 打印 2.11.8 |
| JDK 一致性 | java -version与javac -version | 均为 1.8.x |
| REPL | 敲 for + yield + map | 输出正确集合 |
| IDE | 新建项目 Run | 控制台有输出 |
| 构建(可选) | 添加一个 Scala 2.11 依赖 | 正常解析不报错 |
从那以后我每次配 Scala 环境,都会把这四层强制走一遍,尤其是第二层 REPL,因为它能立刻区分「命令装上了」和「运行时是好的」这两种状态。吃过一次只验证版本号、结果到项目里才发现 SDK 配错的亏,后面就不敢省这几分钟了。希望这套流程能帮到你,少在环境上绕圈,把时间留给 Scala 本身。
至于这份 Scala 学习资料,里面从安装到基础语法、方法和函数都串起来了,配着上面的步骤边装边敲,比只看不练快得多,需要的可以取来对着跑一遍。
本文还有配套的精品资源,点击获取