英文:
What does " _ = c(ctx, cmd)" mean?
问题
_ = c(ctx, cmd)
是一个函数调用语句,它的作用是调用函数 c
并传入参数 ctx
和 cmd
。这里使用 _
是为了忽略函数返回的结果,即不关心函数的返回值。在这段代码中,_ = c(ctx, cmd)
的目的可能是为了执行一些副作用,而不需要使用函数的返回值。至于函数 c
的具体实现,你在代码中找不到它的定义是因为 cmdable
是一个函数类型的别名,它可以被赋值为任何具有相同参数和返回值的函数。所以你需要在其他地方找到 cmdable
类型的具体实现来了解函数 c
的实际行为。你可以在 https://github.com/go-redis/redis/blob/master/commands.go#L780 找到 cmdable
类型的定义。希望对你有帮助!
英文:
I'm reading the code that go-redis library, and then I want to know how the _ = c(ctx, cmd)
works.
// Get Redis `GET key` command. It returns redis.Nil error when key does not exist.
func (c cmdable) Get(ctx context.Context, key string) *StringCmd {
cmd := NewStringCmd(ctx, "get", key)
_ = c(ctx, cmd)
return cmd
}
I found type alias below but I couldn't find this function's body.
type cmdable func(ctx context.Context, cmd Cmder) error
why and how _ = c(ctx, cmd)
works without function body?
https://github.com/go-redis/redis/blob/master/commands.go#L780
Thanks!
答案1
得分: 5
cmdable
被定义为type cmdable func(ctx context.Context, cmd Cmder) error
。因此,它是一个函数的别名,可以从方法中调用自身。这与任何其他函数变量的工作方式相同:
abc := func(ctx context.Context, cmd Cmder) error {
fmt.Println("我们可以在这里做任何事情")
return nil
}
cmd := cmdable(abc)
因此,实际的函数体在此结构体之外提供。例如,它们在几个地方使用,这是Client
的定义:
type Client struct {
*baseClient
cmdable
hooks
ctx context.Context
}
它嵌入了cmdable
,因此cmdable
上的所有公开方法也将成为Client
上的公开方法。在NewClient
中创建Client
时,将cmdable
设置为c.Process
:
func NewClient(opt *Options) *Client {
opt.init()
c := Client{
baseClient: newBaseClient(opt, newConnPool(opt)),
ctx: context.Background(),
}
c.cmdable = c.Process
return &c
}
因此,在Client
的情况下,Client.Process
是c
的函数体。但对于Pipeline
,设置了Pipeline.Process
。他们这样做是因为您希望在提交管道之前排队命令。
因此,这是从抽象结构继承和策略模式的组合。
_ =
丢弃了返回值,该返回值是一个error
。像这样使用下划线被称为空白标识符。这不是严格必要的,但可能是为了向诸如go vet之类的工具表明这是有意的,作者没有忘记检查错误。
英文:
cmdable
is defined as type cmdable func(ctx context.Context, cmd Cmder) error
. So because it is an alias of a function it can call itself from a method. This works just like any other function variable:
abc := func(ctx context.Context, cmd Cmder) error {
fmt.Println("we can do anything here")
return nil
}
cmd := cmdable(abc)
So the actual function body is provided outside of this struct. They use it in a few places for example, this is the definition of Client
:
type Client struct {
*baseClient
cmdable
hooks
ctx context.Context
}
It embeds cmdable
so all exported methods on cmdable
will become exported methods on Client
as well. During creating of the Client
in NewClient
the cmdable is set to c.Process
:
func NewClient(opt *Options) *Client {
opt.init()
c := Client{
baseClient: newBaseClient(opt, newConnPool(opt)),
ctx: context.Background(),
}
c.cmdable = c.Process
return &c
}
So in the case of Client
, Client.Process
is the body of c
. But for Pipeline
, Pipeline.Process
is set. They do this because you want to queue commands before committing the pipeline.
So this is sort of a combination of inheritance from an abstract struct and a strategy pattern.
The _ =
discards the return value which is an error
. Using an underscore like this is called a blank identifier. This is not strictly necessary but is likely done to indicate to tools like go vet that this is on purpose and that the author didn't forget to check an error.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论