【问题标题】:How to decorate functions with different signatures in Golang?如何在 Golang 中用不同的签名装饰函数?
【发布时间】:2019-03-20 16:41:38
【问题描述】:

我尝试应用这个著名的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 和一个错误,所以这应该是可能的。

【问题讨论】:

    标签: go decorator


    【解决方案1】:

    免责声明我所做的唯一修饰是通过嵌入结构,但一种方法是为您想要修饰的函数定义一个类型(不是绝对必要的,但会使签名更简单):

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-13
      • 1970-01-01
      • 1970-01-01
      • 2020-09-29
      • 2018-10-25
      • 2015-02-21
      • 2020-04-01
      • 1970-01-01
      相关资源
      最近更新 更多