美文网首页
1.5.Swift 3使用“Markdown方言”编写代码注释

1.5.Swift 3使用“Markdown方言”编写代码注释

作者: CDLOG | 来源:发表于2018-12-25 14:20 被阅读0次

    作为伴随Swift 3发布的API设计指南中的要求,使用Swift Markdown为代码编写注释已经进一步从一个道义提升为了一种行为准则。一方面,Markdown对开发者来说,足够熟悉,学习难度并不高;另一方面,Xcode可以在Playground和代码提示中,对Markdown注释进行漂亮的渲染,让代码在开发者之间交流起来更加容易。

    从一个包含playground文件的Single View Application开始

    为了演示Markdown注释在Xcode中的各种效果,我们创建一个Single View Application,并向其中添加了一个MyPlayground文件以及一个包含struct IntArray类型的源代码文件。因为,在Xcode在Playground和项目源代码中,使用了两种不同的Markdown注释格式,我们要分别了解它们。

    为了能快速切换Markdown注释在Playground中的渲染效果,我们可以按Command + ,打开属性对话框,选择“Key Bindings”

    Key bindings

    在“Filter”中,输入Show rendered,Xcode会为我们自动过滤出筛选的菜单项目,“Show rendered Markup”用于在Playground里,切换Markdown注释的渲染。双击右侧的空白,为它设定一个快捷键,例如:option + M

    Show rendered markdown

    这样,我们就能通过设置的快捷键在Playground中快速切换Markdown的渲染效果了。接下来,我们就来看各种常用的Markdown用法。


    Playground

    • 包含Markdown的单行注释用//:表示:
    //: # Heading 1
    
    
    • 包含Markdown的多行注释用下面的代码表示:
    /*:
      * item1
      * item2
      * item3
     */
    
    

    Option + M,Playground就会自动为我们渲染注释了:

    Rendered markdown

    Symbol documentation

    如果是在Xcode项目的源代码中:

    • 包含Markdown的单行注释用///表示:
    /// A **demo** function
    func demo() {}
    
    
    • 包含Markdown的多行注释用下面的代码表示:
    /**
      * item1
      * item2
      * item3
    */
    func demo1() {
    }
    
    

    我们这样添加的注释会显示在哪呢?主要有两个地方,Apple管它们叫做symbol documentation,我们可以用两种方式来查阅它:

    • 把光标放到demo1所在的行上,按住option点一下,就会弹出这个函数的说明,可以看到Xcode已经把markdown注释渲染了;
    Rendered markdown
    • Option + Command + 2打开Quick Help Inspector,保持光标在demo1()所在行,同样,我们可以看到被渲染过的Markdown注释;
    Rendered markdown

    简单来说,在Playground里编写markdown注释时,注释起始的第三个字符用:,在项目源代码中编写markdown注释时,注释起始的第三个字母分别用/*


    常用的注释范式

    接下来,我们看来一些在Playground和项目代码中经常会用到的注释范式。至于其中用到的Markdown语法,大家应该都比较熟悉,我们就不一一去解释了。大家也可以在这里查看Apple官方的Swift markdown语法说明


    标记重要事项

    当我们用Playground告知开发者代码中的重要事项时,可以采用下面这种类似的方式进行注释:

    /*:
      > # IMPORTANT: something important you want to mention:
      A general descripiton here.
      1\. item1
      1\. item2
      1\. item3
      ---
      [More info - Access boxueio.com](https://boxueio.com)
     */
    
    
    • 一行简短的重要提示标题;
    • 一段内容摘要;
    • 一个注意事项列表;
    • 一个提供更多内容的链接;

    在Playground里,上面的注释可以被渲染成这样:

    Rendered markdown

    如果我们要把上面的注释放在项目代码里,出了要使用/**开始外,我们还要去掉第一行的>,因为Quick Help不支持这样的Markdown:

    /**
      # IMPORTANT: something important you want to mention:
      A general descripiton here.
      1\. Start with
      1\. Write anything important you want to emphasize
      1\. End with  at a new line.
      ---
      [More info - Access boxueio.com](https://boxueio.com)
     */
    
    

    这样,它看起来,就是这样的:

    Rendered markdown

    有关函数自身的注释范式,稍后我们会看到。接下来,我们先看一个简化注释输入的方法。


    在Playground之间跳转

    有时,为了演示一个项目的不同用法和功能,我们可能会在项目中使用多个Playground文件。为了方便在注释中浏览,我们可以在Playground markdown注释中,添加文件跳转链接。

    选中项目中的MyPlayground,点击右键,选择“New Playground Page”,添加2个新的page进来,我们把这些页面分别命名成Page1 / Page2 / Page3。

    在新添加进来的page2和page3里,先分别添加一个标题注释以方便区分它们。然后我们可以看到,在Playground页面的头部和尾部,Xcode已经为我们自动添加了两个链接:

    //: [Previous](@previous)
    
    //: [Next](@next)
    
    

    Option + M,切换到渲染模式,分别点击页面上的Previous和Next链接,就会发现可以在页面间前后跳转了。实际上,这里用了两个关键字,@previous@next,Xcode会自动把它们渲染成跳转到项目文件列表中前、后两个文件的链接。

    当然,我们也可以实现跨文件跳转,打开Page1,这次在括号里写上要跳转到的目标Playground页面的名字:

    //: [To Page3](Page3)
    
    

    再切换到渲染模式,点击“To Page3”,就可以跳转到相应的Playground页面了。接下来,我们来看如何通过Xcode Code Snippet Library简化复杂注释的输入。


    Code Snippet Library

    首先,把之前我们用过的注释块,抽象成一个内容模板:

    /*:
      > # IMPORTANT: <#something important#>
      <#General description#>
      1\. <#item1#>
      1\. <#item2#>
      1\. <#item3#>
      ---
      [More info - <#ref#>](<#Link#>)
    */
    
    

    基本内容和之前还是一样的,只不过,我们把其中需要输入内容的地方用一对<# ... #>包围了起来,这用于告诉Xcode,这些内容是需要每次用户单独输入的。

    其次,我们选中要添加的代码块,先不要着急拖动,按住等待一会儿,直到鼠标从输入状态变回指针状态;

    第三、把代码块拖动到Code Snippet Library:

    Rendered markdown

    这样,在Code Snippet Library里,就会多出来一项,表示我们新添加的代码片段,在图标的左下角,左右一个“User”字样,表示这是我们自定义的代码片段:

    Rendered markdown

    第四、点击“Edit”按钮,编辑一下这个代码片段:

    Rendered markdown

    其中:

    • Title表示代码片段的名称;
    • Summary表示代码片段的简单说明;
    • Platform表示代码片段在 iOS / macOS / watchOS / tvOS / All 中使用;
    • Language表示代码片段生效的语言;
    • Completion Shortcut表示如何调出这个代码片段,在这里我们选择输入importantnote,当然你可以设置成任何方便使用的内容;
    • Completion Scopes表示上面设置的Completion Shortcut生效范围,All表示在任意位置都生效;

    设置完成后,点击"Done"。这样当我们在Swift代码里输入importantnote的时候,就能调出需要的注释片段,我们只要直接设置其中的内容就好了。

    接下来,我们将看到一些常用的注释范式,它不仅可以让代码易于维护和交流,就像API设计指南中的描述的那样,可以有效的激发我们的设计灵感。


    标记自定义类型的常用范式

    对于一个自定义类型来说,我们要在注释中说明以下问题:

    • 一句话描述;
    • 类型主要功能;
    • 常用的初始化方法以及拷贝语义;
    • 补充说明;

    而对这些问题的阐述,正是我们设计这个类型的过程。因此,在编码前设计注释文档,可以很好的帮我们整理设计思路。

    例如,我们创建一个包含整数的struct IntArray,在Playground里添加下面的注释:

    /*:
     `IntArray` is a C-like random access collection of integers.
    
     ## Overview
     An `IntArray` stores values of integers in an ordered list.
     The same value can appear in an IntArray multiple times at
     different positions.
    
     ## Initializers
     You can create an IntArray in the following ways:
    
        // An empty IntArray
        var empty: IntArray = []
    
        // Initialzied by an array literal
        var odds: IntArray = [0, 2, 4, 6, 8]
    
        // Initialized by a default value
        var tenInts: IntArray = IntArray(repeating: 0, count: 10)
    
     ## Value semantics
     - important:
     `IntArray` object perform value type semantics. But we have the COW optimization.
    
     Like all value types, `IntArray` use a COW optimization.
     Multiple copies of `IntArray` share the same storage as long as
     none of the copies are modified.
    
     ---
    
     - note:
     Check [Swift Standard Library](https://developer.apple.com/reference/swift/array)
     for more informaton about arrays.
     */
    
    

    上面的注释被Xcode渲染出来是这样的:

    Rendered markdown

    而把这段注释移植到Xcode项目代码中,在Quick Help中看到的结果是这样的:

    Rendered markdown

    当然,你可以任意在注释里添加希望其它开发者了解的内容,例如访问、存取、修改数组的方法等。也可以通过Snippet library,把它保存起来。

    在上面的注释里,有几个用法是要特别说明下的:

    • 我们可以在注释中使用single line of code来插入单行代码;
    • 在注释中插入代码块时,代码块的缩进要和当前最近的一个内容缩进有4个以上的空格,否则Xcode不会识别;
    • 我们在注释中使用了两个用-开始的标记,它们叫做callout,实际上你可以选择使用加号、减号或乘号来表示一个callout。Xcode可以识别它们,并突出显示其中的内容。大家可以在这里找到所有的callout元素列表。要说明的是,并不是所有callout都可以同时在Playground和Quick Help中使用,选择的时候,要注意这点;
    • 最后,我们可以使用三个及以上的-,表示一条分割线,用来区分正文和内容引用的部分;

    标记函数或方法的常用范式

    通常,对一个方法的描述,更多是用在Quick Help里。对于一个函数来说,最重要的内容无非有以下:

    • 一句话功能描述;
    • 常见应用场景;
    • 参数;
    • 返回值;
    • 时间复杂度;

    如果我们要在上面IntArray里,添加一个“返回不包括末尾N个元素的IntArray”的方法:

    public func dropLast(_ n: Int) -> IntArray
    
    

    它的注释可以是这样的:

    /// Returns a subsequence containing all but the specified number of final
    /// elements.
    ///
    /// If the number of elements to drop exceeds the number of elements in the
    /// collection, the result is an empty subsequence.
    ///
    ///     let numbers = [1, 2, 3, 4, 5]
    ///     print(numbers.dropLast(2))
    ///     // Prints "[1, 2, 3]"
    ///     print(numbers.dropLast(10))
    ///     // Prints "[]"
    ///
    /// - Parameter n: The number of elements to drop off the end of the collection.
    ///   `n` must be greater than or equal to zero.
    ///
    /// - Returns: A subsequence that leaves off `n` elements from the end.
    ///
    /// - Complexity: O(*n*), where *n* is the number of elements to drop.
    
    

    通常,多行的代码注释也可以使用这种多个单行注释拼接的形式来编写,因为有时多行缩进的不同,会让整个注释从头部看起来比较混乱(大家可以对比下前面我们对IntArray的注释),而使用多个///则看起来会整齐一些。

    在这个例子里,我们使用了三个callout,分别表示了方法的参数、返回值和时间复杂度,如果算法复杂度是O(1),那默认是可以省略的

    在Quick Help里,它看上去是这样的:

    Rendered markdown

    标记属性的常用范式

    关于属性的注释,我们只强调一点,就是对于computed property来说,如果它的算法复杂度不是O(1),必须在注释中予以说明。因为对于绝大多数人来说,不会预期访问一个属性会带来严重的性能开销。

    以上,就是在Swift 3 API设计指南中,关于注释的内容。在编码前,用写文档的方式来编写注释,可能在初期会让我们觉得不适应,或者觉得没必要,但至少在设计一个新的类型或方法时,尝试着去做它们,它会让你明确类型表达的语意,理清方法功能的边界,进而让你的代码,更加易于理解和交流。

    相关文章

      网友评论

          本文标题:1.5.Swift 3使用“Markdown方言”编写代码注释

          本文链接:https://www.haomeiwen.com/subject/ytxlkqtx.html