如果提供一个库,或者提供了一个模块,如何给使用者描述这个API的用法?一般都是给文档,但是文档非常容易不同步,在golang中,有更高级的做法,也是最好的做法。
以go-fdkaac
为例,这个是一个go binding,调用了lib-fdkaac的c函数,提供aac的codec的一个库。
首先,由于用静态库的方式引用,涉及到了如何下载fdkaac的c代码和编译,需要在doc中说明,也就是README.md中说明Usage
:https://github.com/winlinvip/go-fdkaac#usage
在Usage中,准备好代码和环境后,就只需要链接到使用的examples:
解码使用实例,如何使用AAC解码器。而这个使用说明本身就是utest,有期望值,可以运行:
winlin:go-fdkaac winlin$ go test ./...? github.com/winlinvip/go-fdkaac [no test files]ok github.com/winlinvip/go-fdkaac/dec 0.008swinlin: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_testimport ( "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)进去。
总结以上是内存溢出为你收集整理的论golang的文档即代码全部内容,希望文章能够帮你解决论golang的文档即代码所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)