在闭包上使用方法更好吗?

时间:2019-04-10 02:20:01

标签: go methods closures

我有一个简单的数据类型,仅由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

使用闭包是不可能的,它要求调用者使用正确的调用。

如评论中所述,可以使用着色器包并取消导出着色器类型。我之所以没有使用它,是因为我认为制作一个仅包含一个文件的完整软件包是不适当的。但是,如果能够巩固对类型的正确使用,也许是适当的。

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

1 个答案:

答案 0 :(得分:3)

闭包和方法解决了完全不同的问题,因此很少有人问过在特定情况下使用哪种方法。

话虽如此,闭包可以是提供数据保护的一种方式,并且经常在不提供私有变量(例如JavaScript)的语言中被用于此目的。

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