gpt4 book ai didi

go - 从接口(interface)创建处理程序

转载 作者:数据小太阳 更新时间:2023-10-29 03:16:11 30 4
gpt4 key购买 nike

假设我有这个界面

type Selecter interface {
Select(vars ...string) error
}

我想让处理程序在调用 Select 函数后几乎只返回该接口(interface)的 JSON 形式。像这样:

func MakeHandler(s Selecter) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
//... do some stuff to get vars ...
if err := s.Select(v1, v2); err != nil {
//... blah blah errors ...
}
b, err := json.Marshal(s)
if err != nil {
//... blah blah errors ...
}
w.Write(b)
}
}

所以如果 CoolType 是一个 Selecter 我可以这样做

type CoolType struct {
CoolString string `json:"cool_string"`
CoolInt int `json:"cool_int"`
CoolBool bool `json:"cool_bool"`
}

func (c *CoolType) Select(vars ...string) error {
// fill up c using vars
return nil
}

// this looks kinda ugly to me too
fn := MakeHandler(CoolType{})

我对此的根本问题是 s 是一个接口(interface)并使用指针。这将使这在 goroutine 中不安全,因为可以在调用 Select 和调用 Marshal 之间修改 s

我真的认为这是我想要实现它的方式,因为它相当简洁且易于更改,但我认为我遗漏了一些东西。我可以使用 reflect 或更改 Selecter 接口(interface),让 Select 返回一个 interface{},因为我不这样做不必特别在意类型是什么。然后我想在 Select 的每个实现中都制作一个新的类型副本。或者互斥体会起作用。或者也许更好的方法是让我所有的 Selecter 类型只实现 ServeHTTP 并成为一个 http.Handler

无论如何,我假设人们已经尝试过类似的东西并且已经想出了可能更优雅的解决方案,所以我想听听一些想法。

最佳答案

如果您害怕突变,请传递值的副本。为此,您可能必须将界面更改为类似以下内容:

type Selecter interface {
Select(vars ...string) (Selecter, error)
}

并更改您的 Select 方法以获取值接收器来实现接口(interface)。它将是 func (c CoolType) Select(vars ...string) (CoolType, error)

然后将您的 s 作为值而不是指针传递并调用 Select,如下所示:

if s, err := s.Select(v1, v2); err != nil {
//... blah blah errors ...
}

您可以争辩说您丢失了有关类型的信息,但在将值作为选择器接口(interface)传递时您已经丢失了它。

但总的来说你的实现是好的。我的感觉是 Go 中的 elegant 与其他语言有所不同。我想说在 Go 中优雅是可读的、可维护的和准确的——而不是官僚主义和试图保护你自己。

关于go - 从接口(interface)创建处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34737124/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com