在AST的特定实现中,我有一个作为接口(interface)的nodeExprNodeEvalNode和一些叶节点。现在叶节点可以是字符串节点或数字节点或函数节点
每个表达式节点只能有两个叶节点。一左一右。

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上接受的节点类型。

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

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

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

最佳答案

使用以下类型来确保只能将叶子类型分配给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
}

关于go - Golang中表示通用数据类型的惯用方式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58475288/

10-08 22:08
查看更多