Skip to content

Commit

Permalink
update guide
Browse files Browse the repository at this point in the history
  • Loading branch information
dengsgo committed Aug 20, 2023
1 parent 3e855ac commit 6c4b443
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions GUIDE.zh_cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ $ go install github.com/dengsgo/go-decorator/cmd/decorator@latest

### 自定义装饰器

装饰器是普通的 `go` 一级函数(Top-level Function),它的类型是 `func(*decor.Context)`. 只要函数满足这个类型,就可以在项目代码里作为装饰器来装饰其他函数
装饰器是普通的 `go` 一级函数(Top-level Function),它的类型是 `func(*decor.Context)`. 只要函数满足这个类型,它即是合法的装饰器,可以在项目代码里来装饰其他函数

例如, 这里定义一个 logging 装饰器,它可以打印被调用函数的参数:

Expand Down Expand Up @@ -104,7 +104,7 @@ $ ./datetime

### 使用多个装饰器

`decorator` 允许同时使用多个装饰器来装饰目标函数, 但并不推荐这样做
`decorator` 允许同时使用多个装饰器来装饰目标函数。

通过多个 `//go:decor ` 来使用多个装饰器。

Expand All @@ -127,7 +127,7 @@ func datetime(timestamp int64) string {

如果使用了多个装饰器,装饰器执行的优先级为从上往下,也就是说先定义的先被执行。上面的装饰器中,执行顺序为 `logging` -> `appendFile` -> `timeFollowing`.

多个装饰器的使用,可能会导致代码的可读性变差,逻辑流程理解困难,尤其是装饰器本身的代码又特别复杂的情况。因此并不推荐这样使用。
多个装饰器的使用,可能会导致代码的可读性变差,加大逻辑流程理解成本,尤其是装饰器本身的代码又特别复杂的情况。因此并不推荐这样使用。

## Context

Expand Down Expand Up @@ -157,7 +157,10 @@ func datetime(timestamp int64) string {

它从 `ctx.TargetIn` 获取到目标函数入参值,然后执行目标函数代码,再把得到的结果赋值到 `ctx.TargetOut`

如果装饰器中没有执行 `ctx.TargetDo()` ,意味着目标函数真实的逻辑不会被执行,调用目标函数得到的结果是零值(在没有修改 ctx.TargetOut 的情况下)。
如果装饰器中没有执行 `ctx.TargetDo()` ,意味着目标函数真实的逻辑不会被执行,调用目标函数得到的结果是零值(在没有修改 ctx.TargetOut 的情况下)。

> 在编写装饰器代码时要注意,一定要对 ctx.TargetIn、ctx.TargetOut 的元素值断言类型,任何类型错误的赋值都会产生 runtime panic。
> 不要改变 ctx.TargetIn、ctx.TargetOut 值(赋值/追加/删除等),这会导致 ctx.TargetDo() 调用时产生严重错误 panic。
## 包引用

Expand Down Expand Up @@ -206,9 +209,17 @@ func test() {
- **不能**在同一个目标函数上同时使用相同的装饰器重复装饰;
- **不能**对装饰器函数应用装饰器;

## 开发与调试

`decorator` 作为 go 编译链中的一环,编译时被 go 加载使用。它与 go 的编译链保持兼容,不会产生副作用。

开发流程中要改变的只是给用到的 go 命令增加 `-toolexec decorator` 参数,其他完全一致,感觉不到有变化。

你也可以随时取消这个参数。来放弃项目对 go 装饰器的使用。即使代码中保留了 `//go:decor ` 注释也不会有任何副作用(因为它对于标准工具链来说只是无意义的注释而已)。

## 性能

尽管 `decorator` 在编译时会对目标函数做额外的处理,但是相对于原始go代码直接调用装饰器函数来讲,性能几乎没有损失
尽管 `decorator` 在编译时会对目标函数做额外的处理,但它仅仅只构建必要的上下文参数,没有额外开销,更没有反射。相对于原始go代码直接调用装饰器函数来讲,性能几乎是一致的

// TODO 提供性能指标对比

Expand Down

0 comments on commit 6c4b443

Please sign in to comment.