快速实现golang interface
golang中的interface提供了一种非常方便的方式来达到代码重用的目的。
几乎大部分的项目中都会用到interface,在日常工作中,为了实现某个interface,
我发现我也在一直不断的查询GoDocs,只有不断去查,才能知道这个interface中
有哪些方法,这无疑是非常浪费时间的。
例如,为了让我的结构体是可hash的,实现一个hash接口是非常常见的操作。以下是hash
的GoDocs:
type Hash interface {
// Write (via the embedded io.Writer interface) adds more data to the running hash.
// It never returns an error.
io.Writer
// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
Sum(b []byte) []byte
// Reset resets the Hash to its initial state.
Reset()
// Size returns the number of bytes Sum will return.
Size() int
// BlockSize returns the hash's underlying block size.
// The Write method must be able to accept any amount
// of data, but it may operate more efficiently if all writes
// are a multiple of the block size.
BlockSize() int
}
为了实现 hash 接口,我们需要同时实现上述五个方法。
今天我来给大家介绍一种快速实现一个接口的方法。
Impl可以自动的实现一个接口,这非常有用。
如何使用呢? 执行以一下命令即可:
impl <struct-name> <intreface-name>
还是以hash这个结构体为例,具体看一下如何使用impl。
impl Foo hash.Hash
输出:
func (Foo) Write(p []byte) (n int, err error) {
panic("not implemented") // TODO: Implement
}
// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
func (Foo) Sum(b []byte) []byte {
panic("not implemented") // TODO: Implement
}
// Reset resets the Hash to its initial state.
func (Foo) Reset() {
panic("not implemented") // TODO: Implement
}
// Size returns the number of bytes Sum will return.
func (Foo) Size() int {
panic("not implemented") // TODO: Implement
}
// BlockSize returns the hash's underlying block size.
// The Write method must be able to accept any amount
// of data, but it may operate more efficiently if all writes
// are a multiple of the block size.
func (Foo) BlockSize() int {
panic("not implemented") // TODO: Implement
}
执行完上面的命令后,我们没有必要再去不断查询hash的DoDocs去看如何实现一个接口了。
想像一下,如果后面我们需要为Foo结构体实现一个新的接口sortable,将会怎么样呢?同样的
我们也可以使用impl来实现sort的interface,如下:
impl Foo sort.interface
输出:
// Len is the number of elements in the collection.
func (Foo) Len() int {
panic("not implemented") // TODO: Implement
}
// Less reports whether the element with
// index i should sort before the element with index j.
func (Foo) Less(i int, j int) bool {
panic("not implemented") // TODO: Implement
}
// Swap swaps the elements with indexes i and j.
func (Foo) Swap(i int, j int) {
panic("not implemented") // TODO: Implement
}
impl不但可以实现标准库中定义的接口,同样的,它也能实现我们自定义的接口。例如:go-mysql
提供了一个管理mysql数据库的强大的工具集。下面我们为其中的"Handler"接口做一个快速实现:
$ go get github.com/siddontang/go-mysql/server
$ impl Foo server.Handler
输出:
//handle COM_INIT_DB command, you can check whether the dbName is valid, or other.
func (Foo) UseDB(dbName string) error {
panic("not implemented") // TODO: Implement
}
//handle COM_QUERY command, like SELECT, INSERT, UPDATE, etc...
//If Result has a Resultset (SELECT, SHOW, etc...), we will send this as the response, otherwise, we will send Result
func (Foo) HandleQuery(query string) (*server.Result, error) {
panic("not implemented") // TODO: Implement
}
//handle COM_FILED_LIST command
func (Foo) HandleFieldList(table string, fieldWildcard string) ([]*server.Field, error) {
panic("not implemented") // TODO: Implement
}
//handle COM_STMT_PREPARE, params is the param number for this statement, columns is the column number
//context will be used later for statement execute
func (Foo) HandleStmtPrepare(query string) (params int, columns int, context interface{}, err error) {
panic("not implemented") // TODO: Implement
}
//handle COM_STMT_EXECUTE, context is the previous one set in prepare
//query is the statement prepare query, and args is the params for this statement
func (Foo) HandleStmtExecute(context interface{}, query string, args []interface{}) (*server.Result, error) {
panic("not implemented") // TODO: Implement
}
//handle COM_STMT_CLOSE, context is the previous one set in prepare
//this handler has no response
func (Foo) HandleStmtClose(context interface{}) error {
panic("not implemented") // TODO: Implement
}
//handle any other command that is not currently handled by the library,
//default implementation for this method will return an ER_UNKNOWN_ERROR
func (Foo) HandleOtherCommand(cmd byte, data []byte) error {
panic("not implemented") // TODO: Implement
}
是不是很有用呢?