Идиоматический способ представления универсального типа данных в golang - PullRequest
1 голос
/ 20 октября 2019

В конкретной реализации 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.

Приносим искренние извинения, если заголовок выглядел слишком широким.

Вопрос: существует ли лучший способ программирования вышеуказанного сценария.

Примечание: я ищу только идиоматические способы обработки вышеуказанного сценария, а не альтернативные реализации алгоритма.

1 Ответ

0 голосов
/ 20 октября 2019

Используйте следующие типы, чтобы гарантировать, что для 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...