【问题标题】:Is it better to use methods over closures?使用方法而不是闭包更好吗?
【发布时间】:2019-08-31 09:30:49
【问题描述】:

我有一个简单类型的数据,它只包含一个 uint32,但是可以对这个数据执行许多操作。使用此数据的所有文件都位于同一个包中,因此可以访问结构内未导出的 uint32,这是不可取的。我最近了解了闭包的强大功能,想知道是使用包含执行任务的函数的结构体,还是将 uint32 存储在结构体中,然后只使用结构体接收器的方法。

这是 OpenGL 着色器的基本表示。方法和闭包选项在调用者看来是一样的,但在后台执行不同。

关闭:

type Shader struct {
    getID  func() uint32
    delete func()
}

func CreateShader(shader string) Shader {
    var id uint32
    //Do work...
    return Shader{
        getID: func() uint32 {
            return id
        },
        delete: func() {
            gl.DeleteShader(id)
        },
    }
}

方法:

type Shader struct {
    id uint32
}

func CreateShader(shader string) Shader{
    var id uint32
    //Do work...
    return Shader{id: id}
}

func (s Shader) getID() uint32 {
    return s.id
}

func (s Shader) delete() {
    gl.DeleteShader(s.id)
}

这两个选项在使用中都是这样的:

func main() {
    shader := CreateShader("shader.code")
    id := shader.getID()
    fmt.Println(id)
    shader.delete()
}

我想避免的错误使用是调用者可能会在 Shader 不知道的情况下影响 id 类型。类似于:

shader.id = 4102 // or some other change

使用闭包时,这种行为是不可能的,需要调用者使用正确的调用。

如 cmets 中所述,可以使用着色器包并取消导出着色器类型。我没有使用它,因为我认为制作一个完整的包只是为了保存一个文件是不合适的。但是,如果它巩固了对类型的正确使用,也许它是正确的。

与方法相比,闭包版本是否“错误”?是否有任何 golang 标准可以对更适合我的用例的选择进行分类?我希望调用者不要触摸着色器的 id,并认为使用闭包可以更清楚地正确使用着色器类型。

【问题讨论】:

  • 您试图通过闭包来防止哪些误用?第二种方法更惯用,因此应该更清楚如何正确使用。
  • 为什么没有shader包来封装Shader类型及其方法?
  • 如果着色器包只对你的父包有用 - 而不是任何外部代码 - 使用 go internal packages
  • 这更多地是关于代码是否是惯用的,而不是关于它的用例。虽然,这是重要的信息。就个人而言,我认为这是一个有趣的闭包用法。这更像是一个例子,而不是一个实际用例,像 Ceris Limon 说,如果使用方法,正确使用是显而易见的。

标签: go methods closures


【解决方案1】:

闭包和方法解决完全不同的问题,因此您很少会问在特定情况下使用哪一个。

话虽如此,闭包可以是一种提供数据保护的方法,并且通常(ab)用于不提供私有变量的语言(即 JavaScript)中。 p>

没有理由在 Go 中为此目的使用它们。

【讨论】:

  • 我知道指针会导致缓存失败,因为必须查找它们。如果让接收者成为一个指针有明显的开销会影响使用闭包的决定吗?或者这是一个只能在分析后才能确定的决定?另外,每个问题到底解决了什么问题?
  • 我不明白你的问题。 “指针导致缓存失败,因为它们必须被查找”是什么意思?无论如何,如果您关心的是性能,答案总是只能在 profiling 之后才能确定。
猜你喜欢
  • 2015-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-20
  • 2019-12-12
  • 1970-01-01
相关资源
最近更新 更多