Jade Dungeon

Scala代码风格

scala文档的代码风格

原文:https://docs.scala-lang.org/style/scaladoc.html

为所有包,类,特征,方法和其他成员提供文档很重要。Scaladoc通常遵循Javadoc的约定 ,但是还有许多其他功能可以使编写scaladoc更简单。

一般来说,您想要更多地关注实体和写作风格,而不是格式化。Scaladoc需要对代码的 新用户以及经验丰富的用户有用。实现这一点非常简单:从简洁的总结(从有经验的用户 作为参考)开始,增加细节和解释的水平,同时在详细的部分提供更深入的例子(有经验的 用户可以忽略它,但可以对新来者来说是非常宝贵的)。

Scaladoc评论的一般格式应该如下:

/**
 * Provides a service as described.
 *
 * This is further documentation of what we're documenting.
 * Here are more details about how it works and what it does.
 */
def member: Unit = ()

另一个Scaladoc注释样式在第三列中对齐第二个星号下的星号列。Scaladoc工具还接受 Javadoc注释格式,文本位于单个星号之后,由单个空格分隔。由于注释标记对空格敏感, 所以该工具必须能够推断左边距。

对于所需的唯一文档的方法和其他类型的成员是一个简单的简短描述,可以使用单行格式:

/** Does something very simple */
def simple: Unit = ()

请注意,与Javadoc约定相反,文本从注释的第一行开始,但后续文本保持对齐。特别是, 文本对齐在两列的倍数上,因为Scala源通常缩进两列。

AuthorDocs Scaladoc更多的技术信息。

注释的基本原则

  • 描述要先说重点。例如,说「returns true if some condition」而不是「if some condition return true」。
  • 描述方法的第一句话要用「返回XXX」这种固定的格式。如「返回列表的第一个元素」, 而不是「此方法返回」或「获取第一个」等等。方法通常有返回值。
  • 这同样适用于类; 省略「这个类XXX」; 只要说「XXX」
  • 使用方括号语法创建引用其他类的链接,例如[[scala.Option]]
  • @return注释中总结方法的返回值,把更长更详细的描述放在文档主体里。
  • 如果方法的文档主体对返回值进行了详细的描述,就不要再在@return注释重复啰嗦一遍了。
  • 手册中包含的内容是「做了什么」而不是「应该要做的」。换句话说,说「将f应用到x的结果」,而不是「将f应用到x的结果」。微妙但重要。
  • 当引用到类的实例时,请使用「本XXX」或「此」而不是「XXX」。对于单例Object,说「这个单例」。
  • 使代码示例与文档一致。
  • 尽可能使用wiki风格的语法而不是HTML。
  • 示例应该使用完整的代码列表或REPL,具体取决于需要的内容(最简单的方法是使用REPL代码来开发REPL中的示例并将其粘贴到Scaladoc中)。
  • 自由使用@macro来指代需要特殊格式化的常用重复值。

关于包的scaladoc

要为每个包提供Scaladoc,形式是在这个包所对应目录下提供package.scala文件。 比如对于包parent.package.name.mypackage,有以下文件:

package parent.package.name

/** This is the Scaladoc for the package. */
package object mypackage {
}

软件包的文档应该首先记录哪些类是包的一部分。其次,记录包对象本身提供的各种各样的事情。

虽然软件包文档不需要是关于在软件包中使用类的完整教程,但它应该提供主要类的概述, 以及如何使用该软件包中的类的一些基本示例。请务必使用方括号表示法引用类:

package my.package
/** Provides classes for dealing with complex numbers.  Also provides
 *  implicits for converting to and from `Int`.
 *
 *  ==Overview==
 *  The main class to use is [[my.package.complex.Complex]], as so
 *  {{{
 *  scala> val complex = Complex(4,3)
 *  complex: my.package.complex.Complex = 4 + 3i
 *  }}}
 *
 *  If you include [[my.package.complex.ComplexConversions]], you can
 *  convert numbers more directly
 *  {{{
 *  scala> import my.package.complex.ComplexConversions._
 *  scala> val complex = 4 + 3.i
 *  complex: my.package.complex.Complex = 4 + 3i
 *  }}}
 */
package complex {}

关于类、单例对象和特质的scaladoc

要为所有的类、单例对象和特质提供文档。文档的第一句话要写明本类到底做了什么。 所有的类型参数都要用@tparam注释。

如果一个类使用伴随对象创建,就需要在类的描述之后注明这一点(具体细节留在伴随对 象的文档里详细说)。虽然目前还没有办法直接创建一个到伴侣对象的链接,但是生成的 Scaladoc会在类文档输出中为你创建一个链接。

如果使用构造函数创建类,请使用以下@constructor语法:

/** A person who uses our application.
 *
 *  @constructor create a new person with a name and age.
 *
 *  @param name the person's name
 *  @param age the person's age in years
 */
class Person(name: String, age: Int) {
}

根据类的复杂性,可以提供常见用法的示例。

单例对象

由于单例对象可以用于各种目的,重要的是记录如何使用对象(例如作为工厂,用于隐式 方法)。如果此对象是其他对象的工厂的话,在文档里要特别说明这一点。 将该apply()方法的细节写清楚。如果你的对象不使用apply()作为工厂方法, 请务必标明实际的方法名:

/** Factory for [[mypackage.Person]] instances. */
object Person {

  /** Creates a person with a given name and age.
   *
   *  @param name their name
   *  @param age the age of the person to create
   */
  def apply(name: String, age: Int) = {}

  /** Creates a person with a given name and birthdate
   *
   *  @param name their name
   *  @param birthDate the person's birthdate
   *  @return a new Person instance with the age determined by the
   *          birthdate and current date.
   */
  def apply(name: String, birthDate: java.util.Date) = {}
}

如果带有隐式转换,应该提供例子:

/** Implicit conversions and helpers for [[mypackage.Complex]] instances.
 *
 *  {{{
 *  import ComplexImplicits._
 *  val c: Complex = 4 + 3.i
 *  }}}
 */
object ComplexImplicits {}

特质

概述了特质作用之后,提供一些必须在混合特质的类中指定的方法和类型的概述。 如果有已知的类使用trait,请引用它们。

方法和其他成员

应该为所有的方法和成员提供文档。和其他类型内容的文档一样,第一句应该是该方法 执行内容的总结。后续句子进一步详细解释。记录每个参数以及每个类型参数 (类型参数用@tparam)。

对于柯里化的函数,请考虑提供有关预期或习惯用法的更详细的示例。

对于隐式参数,请特别注意说明这些参数来自哪里,以及用户是否需要进行额外的工作以确保参数可用。