我有一个简单的数据类型,仅由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,并认为使用闭包可以更清楚地正确使用着色器类型。
答案 0 :(得分:3)
闭包和方法解决了完全不同的问题,因此很少有人问过在特定情况下使用哪种方法。
话虽如此,闭包可以是提供数据保护的一种方式,并且经常在不提供私有变量(例如JavaScript)的语言中被用于此目的。
没有理由在Go中为此目的使用它们 。