我尝试应用这个著名的Golang decorators talk中的装饰器,但是它仅对他有用,因为他装饰的所有函数都附加到一个结构上,而他只是装饰一个Do()函数。我见过的所有其他教程也都采用这种方式,这很烦人。
我想用base58 / 64编码器功能修饰这些功能
func SpendTx(senderID, recipientID string, amount, fee utils.BigInt, payload string, ttl, nonce uint64) (rlpRawMsg []byte, err error)
func NamePreclaimTx(accountID, commitmentID string, fee uint64, ttl, nonce uint64) (rlpRawMsg []byte, err error)
func NameClaimTx(accountID, name string, nameSalt, fee uint64, ttl, nonce uint64) (rlpRawMsg []byte, err error)
...
如您所见,参数都是不同的,它们也是纯函数,没有附加到结构上。但是它们都返回[] byte和错误,因此应该可行。
答案 0 :(得分:0)
免责声明,我唯一要做的修饰就是通过嵌入结构,但是一种方法可以是为您想要修饰的函数定义类型(并非绝对必要,但会使签名更简单):
type SpendTXFn = func SpendTx(senderID, recipientID string, amount, fee utils.BigInt, payload string, ttl, nonce uint64) (rlpRawMsg []byte, err error)
现在函数可以用这种类型进行对话,装饰器函数将包含与此类型相同的调用签名
func EncodedSpendTX(s SpendTX) SpendTX {
return func(senderID, recipientID string, amount, fee utils.BigInt, payload string, ttl, nonce uint64) (rlpRawMsg []byte, err error) {
// compute decorated result
res, err := s(senderID, recipientID, amount, fee, payload, ttl, nonce)
if err != nil {
return res, err
}
// encode the res
// return encoded res
}
}
现在您可以装饰SpendTX功能:
decorated := EncodedSpendTX(originalSpendTx)
decorated(...) -> []byte, err
缺点是每种功能类型都有一个装饰器。 many with my favorite being的优点是,编码易于测试并且与原始逻辑分离,因此不需要对原始函数进行任何更改。
实际上,我认为这是go的http中间件通过http.Handler
采取的方法
https://www.alexedwards.net/blog/making-and-using-middleware