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"

这条语句中包含了三个关键部分:

  • groupIdcom.typesafe.akka
  • artifactIdakka-actor
  • version2.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 大版本时能减少很多不必要的麻烦。


原始标题:Difference Between % and %% Symbols in build.sbt

» 下一篇: Cake 模式