go - 将结构方法作为参数传递
问题描述
我不确定我是否试图超出 Go 允许的限制,但这里是上下文:我Map
使用大量有用的成员函数调用类型,例如Interpolate
,Add
和Clear
. 我还有一个 struct 类型,Layered
它包含几个Map
s。
type Map [][]float64
func (m Map) Interpolate(min, max float64) { ... }
func (m Map) Add(val float64) { ... }
func (m Map) Clear() { ... }
type Layered struct {
data []Map
}
我想添加一个成员函数,Layered
它接受任何成员函数Map
作为参数,然后在其包含的所有Map
s 上调用它。类似于以下内容:
func (l Layered) MapCall(callMe func(Map)) {
for _, m := range l.data {
callMe(m)
}
}
这部分有效,但仅适用于不带额外参数的成员函数Map
,例如Clear
. 是否有可能接受任何成员函数Map
作为参数(以及其形式的潜在参数...interface{}
),然后Map
在 a 中的所有成员上调用具有正确参数的函数Layered
?像这样的东西,例如:
func (l Layered) MapCall(callMe func(Map, ...interface{}), params ...interface{}) {
for _, m := range l.data {
callMe(m, params...)
}
}
解决方案
您可能希望比尝试使用接口更具功能性。
Interpolate
我将使用您的方法提供一个示例。
您可以首先定义一个用于生成操作的辅助函数:
func InterpolateOp(min, max float64) func(Map) {
return func(m Map) {
m.Interpolate(min, max)
}
}
另一个更适合您的MapCall
功能的名称是MapInterpolate
.
然后,在使用MapCall
或创建操作列表时,您可以使用之前使用的相同类型,即func(Map)
:
var l Layered
...
l.MapCall(InterpolateOp(2, 4))
该解决方案的关键在于将数据绑定到组成函数的闭包上,从而解决了最初的问题:没有足够的数据来调用相应的函数。
在您的情况下,如果有很多方法不值得这样做,那么您可能会考虑代码生成,因为它是重复且容易的。这超出了这个问题的范围。
另见:https ://dave.cheney.net/2016/11/13/do-not-fear-first-class-functions
推荐阅读
- wordpress - .htaccess 301 带有查询字符串和特殊字符
- r - 如何用三个分类变量进行方差分析?
- batch-file - 使用模式命令调整大小命令提示符清除整个屏幕
- amazon-web-services - AWS Cognito 在首次登录时未提示 MFA
- reactjs - React Graphql Typescript 文件设置
- django - 在 django 模型中保存一个带有前缀和主键的字符字段列?
- c++ - 函数定义/实现的返回值范围内的私有是什么意思(c++)?
- python - DEAP:使突变概率取决于代数
- php - Craft - 动态添加电子邮件收件人错误
- python - Python - 使用交互式 CLI 过滤列表