在AST的特定实现中,我有一个node
,它是一个接口以及ExprNode
,EvalNode
和一些叶节点。现在叶节点可以是字符串节点或数字节点或函数节点
每个表达式节点只能有两个叶节点。左一,右一。
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上接受的节点类型。
诚挚的道歉,如果标题看起来太宽泛。
问题:是否有更好的编程上述方案的方法。
注意:我只是在寻找惯用的方式来处理上述情况,而不是在寻找算法的替代实现。
答案 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
}