论golang的文档即代码

GO TEST

如果提供一个库,或者提供了一个模块,如何给使用者描述这个API的用法?一般都是给文档,但是文档非常容易不同步,在golang中,有更高级的做法,也是最好的做法。

go-fdkaac为例,这个是一个go binding,调用了lib-fdkaac的c函数,提供aac的codec的一个库。

首先,由于用静态库的方式引用,涉及到了如何下载fdkaac的c代码和编译,需要在doc中说明,也就是README.md中说明Usagehttps://github.com/winlinvip/go-fdkaac#usage

在Usage中,准备好代码和环境后,就只需要链接到使用的examples:

而这个使用说明本身就是utest,有期望值,可以运行:

winlin:go-fdkaac winlin$ go test ./...
?       github.com/winlinvip/go-fdkaac  [no test files]
ok      github.com/winlinvip/go-fdkaac/dec  0.008s
winlin:go-fdkaac winlin$

文档变成了可以执行的代码,或者说,没有了经常变化的文档,只有代码,golang这点做得真是perfect!

而example的package,和API的package是不一样的。这个和utest是不一样的,utest因为要访问package内部的内容,所以和API同一个package,比较方便。example因为是给用户用的例子,当然和API的package不能一样,也不可能一样。

GOLANG的Example,强迫API设计者,能从User角度出发,将API设计得很简单易懂,因为复杂的API不好用在写Example时很容易就发现了:

package dec_test

import (
    "fmt"
    "github.com/winlinvip/go-fdkaac/dec"
)

func ExampleAacDecoder_RAW() {
    var err error
    d := dec.NewAacDecoder()

    asc := []byte{0x12,0x10}
    if err := d.InitRaw(asc); err != nil {
        fmt.Println("init decoder failed,err is",err)
        return
    }
    defer d.Close()

    // directly decode the frame to pcm.
    var pcm []byte
    if pcm,err = d.Decode([]byte{
        0x21,0x17,0x55,0x35,0xa1,0x0c,0x2f,0x00,0x50,0x23,0xa6,0x81,0xbf,0x9c,0x13,0x73,0xa9,0xb0,0x41,0xed,0x60,0x48,0xf7,0x34,0x07,0x12,0x53,0xd8,0xeb,0x49,0xf4,0x1e,0xc9,0x01,0xfd,0x16,0x9f,0x8e,0xb5,0xd5,0x9b,0xb6,0xdb,0x61,0x3b,0x54,0xad,0x5f,0x9d,0x94,0x88,0x58,0x89,0x33,0xc4,0x09,0x80,0xa2,0x28,0x42,0x10,0x05,0xfb,0x03,0xc7,0x64,0xe1,0xf6,0x65,0x15,0x38}); err != nil {
        fmt.Println("decode failed,err)
        return
    }

    fmt.Println("SampleRate:",d.SampleRate())
    fmt.Println("FrameSize:",d.FrameSize())
    fmt.Println("NumChannels:",d.NumChannels())
    fmt.Println("AacSampleRate:",d.AacSampleRate())
    fmt.Println("Profile:",d.Profile())
    fmt.Println("AudioObjectType:",d.AudioObjectType())
    fmt.Println("ChannelConfig:",d.ChannelConfig())
    fmt.Println("Bitrate:",d.Bitrate())
    fmt.Println("AacSamplesPerFrame:",d.AacSamplesPerFrame())
    fmt.Println("AacNumChannels:",d.AacNumChannels())
    fmt.Println("ExtensionAudioObjectType:",d.ExtensionAudioObjectType())
    fmt.Println("ExtensionSamplingRate:",d.ExtensionSamplingRate())
    fmt.Println("NumLostAccessUnits:",d.NumLostAccessUnits())
    fmt.Println("NumTotalBytes:",d.NumTotalBytes())
    fmt.Println("NumBadBytes:",d.NumBadBytes())
    fmt.Println("NumTotalAccessUnits:",d.NumTotalAccessUnits())
    fmt.Println("NumBadAccessUnits:",d.NumBadAccessUnits())
    fmt.Println("SampleBits:",d.SampleBits())
    fmt.Println("PCM:",len(pcm))

    // Output:
    // SampleRate: 44100
    // FrameSize: 1024
    // NumChannels: 2
    // AacSampleRate: 44100
    // Profile: 1
    // AudioObjectType: 2
    // ChannelConfig: 2
    // Bitrate: 31352
    // AacSamplesPerFrame: 1024
    // AacNumChannels: 2
    // ExtensionAudioObjectType: 0
    // ExtensionSamplingRate: 0
    // NumLostAccessUnits: 0
    // NumTotalBytes: 91
    // NumBadBytes: 0
    // NumTotalAccessUnits: 1
    // NumBadAccessUnits: 0
    // SampleBits: 16
    // PCM: 4096
}

这个API设计时,最初是和fdkaac一样,有Fill([]byte)然后是Decode(),分成了两步,可以多次Fill。后来发现这个实在不好用,不如直接Decode([]byte),可以用Decode(nil)进去。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


类型转换 1、int转string 2、string转int 3、string转float 4、用户结构类型转换
package main import s "strings" import "fmt" var p = fmt.Println func main() { p("Contains: ", s.Contains("test&quo
类使用:实现一个people中有一个sayhi的方法调用功能,代码如下: 接口使用:实现上面功能,代码如下:
html代码: beego代码:
1、读取文件信息: 2、读取文件夹下的所有文件: 3、写入文件信息 4、删除文件,成功返回true,失败返回false
配置环境:Windows7+推荐IDE:LiteIDEGO下载地址:http://www.golangtc.com/downloadBeego开发文档地址:http://beego.me/docs/intro/ 安装步骤: 一、GO环境安装 二、配置系统变量 三、Beego安装 一、GO环境安装 根
golang获取程序运行路径:
Golang的文档和社区资源:为什么它可以帮助开发人员快速上手?
Golang:AI 开发者的实用工具
Golang的标准库:为什么它可以大幅度提高开发效率?
Golang的部署和运维:如何将应用程序部署到生产环境中?
高性能AI开发:Golang的优势所在
本篇文章和大家了解一下go语言开发优雅得关闭协程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1.简介本文将介绍首先为什么需要主...
这篇文章主要介绍了Go关闭goroutine协程的方法,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。1.简介本文将介绍首先为什么需要主动关闭gor...
本篇文章和大家了解一下go关闭GracefulShutdown服务的几种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录Shutdown方法Regi...
这篇文章主要介绍了Go语言如何实现LRU算法的核心思想和实现过程,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。GO实现Redis的LRU例子常
今天小编给大家分享的是Go简单实现多租户数据库隔离的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会...
这篇“Linux系统中怎么安装NSQ的Go语言客户端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希
本文小编为大家详细介绍“怎么在Go语言中实现锁机制”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么在Go语言中实现锁机制”文章能帮助大家解决疑惑,下面...
今天小编给大家分享一下Go语言中interface类型怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考