1. 简介

良好的文档是软件开发中的关键因素,它能显著提升项目的可维护性。

Scaladoc 是一个文档生成系统,能够读取 Scala 源码中特定格式的注释,并生成编译后的文档。它与 Java 中的 Javadoc 非常相似。

在本教程中,我们将学习如何为 Scala 项目添加 Scaladoc 注释,然后生成文档,并最终查看生成的结果。

2. 在代码中添加 Scaladoc

要添加 Scaladoc,我们可以使用一种特殊的注释块,称为 Scaladoc 注释。它的结构与普通的多行注释非常相似,但关键区别在于开头使用了三个斜杠中的两个星号。

我们来对比一下 Scaladoc 与普通注释:

// 这是单行注释

/*
 * 这是普通多行注释
 */

/** 这是 Scaladoc 注释。
  * 
  */

Scaladoc 注释可以放在包、类、方法、特质(trait)或对象的上方。在接下来的小节中,我们将分别介绍这些用法。

2.1. 包(Package)

包的文档应说明该包的作用以及包含的类

首先,我们需要在文件 package.scala 中创建一个包对象。Scala 会使用这个对象来生成文档。

现在,我们为包添加 Scaladoc:

package com.baeldung.scala

/** 用于 Scaladoc 教程的包。
  * 提供 Scaladoc 示例及其元素,如标签和格式化。
  *
  * 该包中实现的类为 [[com.baeldung.scala.scaladoc.IntervalTimer]]。
  */
package object scaladoc {}

注意,我们使用了双中括号 [[...]] 来引用包中的类 IntervalTimer

2.2. 类(Class)

类文档应说明类的功能以及如何使用它

我们为 IntervalTimer 类编写 Scaladoc:

package com.baeldung.scala.scaladoc

/** 表示一个具有间隔的定时器。
  *
  * 指定定时器的重复次数 `reps` 和每次重复之间的间隔 `interval`
  *
  * @constructor 创建一个指定 `reps` 和 `interval` 的定时器
  * @param reps 定时器将运行的重复次数
  * @param interval 每次重复之间的时间间隔,单位为秒。默认值为 30 秒。
  */
class IntervalTimer(val reps: Int, val interval: Int = 30) { }

其中,@constructor 标签用于解释构造函数的作用,而 @param 用于说明构造函数的参数。

2.3. 方法(Method)

方法文档应说明调用该方法会产生的行为

我们为 IntervalTimer 类添加一个 start 方法及对应的 Scaladoc:

/** 根据定义的 `reps` 和 `interval` 启动定时器。
  *
  * 每秒打印一次消息,每完成一次重复时打印一次完成信息。
  * 此方法无法被停止。
  */
def start(): Unit = {
  Array.range(1, reps + 1).foreach { rep =>
    Array.range(1, interval + 1).foreach { second =>
      Thread.sleep(1000)
      println(s"tic toc $second")
    }
    println(s"rep $rep is finished.")
  }
}

如果方法有返回值,应使用 @return 标签说明返回内容:

/** 获取该定时器的总时间(以秒为单位)。
  *
  * @return 定时器的总秒数。
  */
def getTotalSeconds: Int = {
  interval * reps
}

2.4. 特质(Trait)

特质文档应说明其整体功能以及使用该特质的类必须实现的方法。如果可能,还应列出使用该特质的类。

我们来看一下特质 Carnivore 的文档:

/** 定义一个肉食动物。
  *
  * 使用此特质的类必须实现 movement 方法。
  * 被 [[com.baeldung.scala.scaladoc.TasmanianDevil]] 使用。
  */
trait Carnivore {
  def food: String = "meat"
  def movement: String
}

2.5. 对象(Object)

对象文档应说明其用途(如工厂模式、隐式方法等),如果对象中实现了方法,也应对这些方法进行说明。

我们来看一个工厂对象 TasmanianDevil

package com.baeldung.scala.scaladoc

/** [[com.baeldung.scala.scaladoc.TasmanianDevil]] 实例的工厂。
  *
  * 继承自 [[com.baeldung.scala.scaladoc.Carnivore]]。
  */
object TasmanianDevil extends Carnivore {
  /** 创建一个指定长度的袋獾。
    *
    * @param length 袋獾的长度,单位为厘米。
    */
  def apply(length: Int) = {}
  def movement: String = "Walk"
}

3. 格式化与标签

在 Scaladoc 中,我们可以使用 wiki-style 标记标签 来传达不同类型的信息。

3.1. Wiki-Style 标记

下面是一些基本的格式化语法:

/** Scaladoc 格式化示例:
  *
  * =标题=
  * ==子标题==
  * `等宽字体`
  * ''斜体''
  * '''粗体'''
  * __下划线__
  * ^上标^
  * ,,下标,,
  */

创建链接时,可以使用双中括号:

/** [[实体 链接]],例如 [[scala.collection.Seq]]
  * [[https://external.link 外部链接]],
  * 例如 [[https://scala-lang.org Scala 官网]]
  */

如果需要插入代码示例,可以使用三重花括号:

/** {{{
  * val example = 1
  * }}}
  */

列表

列表项需要使用相同格式和层级,并且不能被其他块打断。

无序列表使用 - 符号:

/** 这是一个无序列表:
  *
  *  - 第一项
  *  - 第二项
  *    - 第二项的子项
  *    - 另一个子项
  *  - 第三项
  */

有序列表可以使用 1.i.I.a.

/** 这是一个有序列表:
  *
  *  1. 第一项
  *  1. 第二项
  *    i. 第二项的子项
  *    i. 另一个子项
  *  1. 第三项
  */

注意:列表项前必须有空格,缩进越多表示层级越深。

3.2. 标签(Tags)

Scaladoc 提供了一些预定义标签,用于添加额外信息:

  • @author:指定类的作者
  • @constructor:说明构造函数的功能
  • @param:描述方法参数或输入
  • @return:说明方法返回值
  • @since:标明类、字段或方法加入项目的版本
  • @version:标明软件版本,通常配合 %I%%G% 宏使用
  • @throws:说明异常抛出的情况
  • @deprecated:说明代码为何被弃用、何时弃用以及替代方案
  • @todo:标记方法或类中尚未完成的部分

4. 生成 Scaladoc

在代码中添加好 Scaladoc 注释后,可以在 sbt 项目的根目录下通过命令行生成文档:

user@baeldung:~$ sbt doc

生成的文档位于:target/scala-{version}/api/index.html

我们打开该文件查看生成结果:

Scaladoc 主页

页面左侧显示我们为包 com.baeldung.scala.scaladoc 创建的文档;右侧显示该包中包含的类和对象。

点击 IntervalTimer 可以查看详细的类文档:

IntervalTimer 类文档

页面上半部分显示类的说明,下半部分显示构造函数和成员方法。点击方法可查看其详细说明。

5. 总结

本教程中,我们学习了如何使用 Scaladoc 为 Scala 代码编写文档,并通过命令行生成文档,还查看了最终生成的效果。

所有示例代码都可以在 GitHub 仓库 中找到。


原始标题:Writing to a File in Kotlin