Golang函数类型与结构的绑定?

时间:2018-04-22 21:01:34

标签: function go struct types binding

这可能看起来像一个愚蠢的问题,但我想用一组函数创建一个结构,但函数绑定到结构。我可以看到这是一个循环,但用这个例子幽默我:

type FuncType func() error

type FuncSet struct {
  TokenVariable  int
  FuncTyper      FuncType
}

我希望能够创建一个绑定到FuncSet类型的函数,以便它可以在TokenVariable上运行,因此:

func (f *FuncSet) FuncType() error {
  f.TokenVariable = 100
  return nil
}

但是,这会更改类型的签名(我无法找到有关类型绑定的任何信息作为函数类型规范的一部分),因此将此函数分配给struct元素会告诉我找不到此函数/变量

我可以看到一个简单的解决方法,通过在参数前面添加一个指向结构类型的指针,它只是有点难看。

我进一步环顾四周,发现我所寻找的东西就像一个封闭物,因为它可以从直接的外部范围传递一个变量,但是......好吧,我将会是很高兴能够纠正函数类型中缺少类型绑定,但是现在将指针传递给类型看起来就像要走的路一样。

我想我找到了解决方案:

type nullTester func(*Bast, uint32) bool

type Bast struct {
  ...
  isNull    nullTester
  ...
 }

func isNull(b *Bast, d uint32) bool {
  return d == 0
}

然后我可以将它绑定到这样的类型:

func NewBast() (b *Bast) {
  ...
  b.isNull = isNull
  ...
}

// IsNull - tests if a value in the tree is null
func (b *Bast) IsNull(d uint32) bool {
  return b.isNull(b, d)
}

看起来有点hackish,我不确定在我要编写的第二个库中会发生什么,为uint32参数设置不同的类型,但是兽医很高兴所以也许这样是正确的方法。

在我看来,func类型应该在语法中确实有一个字段来指定绑定类型,但也许我只是发现了一个hack,sorta让我做多态。在调用程序时,他们将看到的是一个很好的导出函数,它按计划绑定到类型,我获得了可读性,并且能够重新定位基本库以存储不同类型的数据。

我认为这是正确的解决方案。我无法找到任何确认或否认类型名称func规范是否有任何断言类型的方法。它确实不应该匹配,因为绑定签名的一部分,但带有函数的类型的语法似乎没有这种类型的绑定。

我的实际代码在这里,您可以通过查看我的目标来看到: https://github.com/calibrae-project/bast/blob/master/pkg/bast/bast.go

树存储的数据类型之间的差异完全是肤浅的,因为它主要用于对不同长度的无符号整数进行排序,并且它需要具备的一个重要事项是能够从a中工作,例如,64位整数但仅按第一个或后一个整数排序(因为我有一个更大的项目,将这些哈希值视为邻接列表中的坐标)。从理论上讲,它也可以用来代替哈希表查找,由于二叉树结构,找到元素的时间差很小。

它不是传统的基于参考矢量的树,而商店本身就是一个具有两种映射的非传统能力的阵列,一个密集的'树,以及最重要的目的,为了实现这种方式,当树被走动以及旋转时,大多数时候它是连续的存储器块被访问,这应该比传统的更少的缓存未命中二叉树(因此通常这种类型的应用程序只使用某种类型的排序)。

1 个答案:

答案 0 :(得分:2)

您可以使用带有接口的匿名字段,该接口定义您要使用的方法集(可能会更改)。

Go playground here

您已定义界面

type validator interface {
    IsRightOf(a, b interface{}) bool

    ... // other methods
}

和你的类型:

type Bast struct {
    validator // anonymous interface field

    ... // some fields
}

然后您可以从Bast类型

访问验证器的方法
b := bast.New()
b.IsRightOf(c, d) // this is valid, you do not need to do b.validator.IsRightOf(...)

因为验证器是一个接口,您可以根据自己的喜好更改这些方法。