1. 简介
Simple Build Tool(简称 sbt)是 Scala 生态中最常用的构建工具之一。对于刚接触 sbt 的开发者来说,build.sbt
文件的语法可能会有些令人困惑。本文将重点讲解在定义依赖时 %
和 %%
两个符号的区别。
2. 一个简单的 build.sbt
文件示例
我们先来看一个最基础的 build.sbt
文件内容:
name := "build_sample"
version := "0.1"
scalaVersion := "2.12.11"
这是一个没有外部依赖的极简项目。接下来我们会逐步介绍如何添加依赖,并解释 %
和 %%
在其中的作用。
3. 添加外部依赖
假设我们要为项目引入 akka-actor
这个库,通常我们会这样写:
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.6.6"
这条语句中包含了三个关键部分:
- groupId:
com.typesafe.akka
- artifactId:
akka-actor
- version:
2.6.6
而这些部分之间通过一个或两个百分号 %
分隔开来。下面我们就来详细看看 %
和 %%
的区别。
3.1. 使用 Scala 库依赖 ✅
和 Java 不同的是,Scala 的不同版本之间不保证二进制兼容性。比如你不能直接在一个 Scala 2.13 的项目里使用一个只支持 Scala 2.12 的库。
为了避免手动指定 Scala 版本带来的麻烦,sbt 提供了 %%
符号。当你使用 %%
时,sbt 会自动根据当前项目的 scalaVersion
来解析对应版本的依赖。
例如:
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.6.6"
此时 sbt 会自动将其转换成类似这样的形式:
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.12" % "2.6.6"
如果你手动指定 Scala 版本号,就得用单个 %
,并把版本号拼接到 artifactId 后面:
libraryDependencies += "com.typesafe.akka" % "akka-actor_2.12" % "2.6.5"
⚠️ 如果你忘记加 _2.12
这样的后缀,刷新 sbt 时就会报错:
[error] (update) sbt.librarymanagement.ResolveException: Error downloading com.typesafe.akka:akka-actor:2.6.5
[error] not found: /home/administrator/.ivy2/local/com.typesafe.akka/akka-actor/2.6.5/ivys/ivy.xml
[error] not found: https://repo1.maven.org/maven2/com/typesafe/akka/akka-actor/2.6.5/akka-actor-2.6.5.pom
[error] (ssExtractDependencies) sbt.librarymanagement.ResolveException: Error downloading com.typesafe.akka:akka-actor:2.6.5
3.2. 使用 Java 库依赖 ✅
如果是纯 Java 的库(比如 joda-time),则始终使用单个 %
即可:
libraryDependencies += "joda-time" % "joda-time" % "2.10.6"
因为 Java 库本身不区分 Scala 版本,所以不需要 sbt 自动追加 Scala 版本号。
4. 总结
总结一下:
符号 | 场景 | 是否自动追加 Scala 版本 |
---|---|---|
% |
Java 库 / 手动指定 Scala 版本 | ❌ |
%% |
Scala 库(推荐方式) | ✅ |
简单粗暴地说:只要是 Scala 的库,就用 %%
;Java 库则统一用 %
。
这样既省心又不容易出错,特别是在升级 Scala 大版本时能减少很多不必要的麻烦。