Golang中表示通用数据类型的惯用方式

时间:2019-10-20 17:01:44

标签: go

在AST的特定实现中,我有一个node,它是一个接口以及ExprNodeEvalNode和一些叶节点。现在叶节点可以是字符串节点或数字节点或函数节点 每个表达式节点只能有两个叶节点。左一,右一。

type Node interface{
  Pos() int64
  Typ() NodeType 
}

type StringNode struct{
  Pos int64
  Val string
  Node
}

type NumberNode struct {
  Pos int64
  Val float64
  Node
}

type ExprNode struct {
  Lhs  ???  //should accept either StringNode or NumberNode 
  Op   Operation
  Rhs  ???  //should accept either StringNode or NumberNode 
  Node
}

type EvalNode struct{
  Lhs     *ExprNode
  AllFlag bool
  Rhs     *ExprNode
  Node
}

我想出了一个可能不是惯用的解决方法。我在寻找是否有更好的方法

type LeafNode interface{
  IsLeaf() bool
}

func (n *StringNode) IsLeaf() bool{
  return true
}

func (n *NumberNode) IsLeaf() bool{
  return true
}

type ExprNode struct {
  Lhs  LeafNode   //workaround
  Op   Operation
  Rhs  LeafNode   //workaround
  Node
}

现在在上述解决方法中,IsLeaf()函数对我而言并不重要,但是我不得不使用它来限制ExprNode上接受的节点类型。

诚挚的道歉,如果标题看起来太宽泛。

问题:是否有更好的编程上述方案的方法。

注意:我只是在寻找惯用的方式来处理上述情况,而不是在寻找算法的替代实现。

1 个答案:

答案 0 :(得分:0)

使用以下类型来确保只能将叶子类型分配给ExprNode.Lhs和Exprnode.Rhs:

type Node interface{
  Pos() int64
  Typ() NodeType 
}

type LeafNode interface {
  Node
  Leaf() // sentinel function to distinguish leaf types from other types
}

func (*NumberNode) Leaf() {}
func (*StringNode) Leaf() {}

type ExprNode struct {
  Lhs  LeafNode 
  Op   Operation
  Rhs  LeafNode 
  Node
}