接口的混淆问题

huangapple go评论80阅读模式
英文:

Confusion with interfaces

问题

我正在使用Go语言编写一个解析器,并且有以下用于构建抽象语法树的代码:

type NODE interface {
	GetPosition() (int, int)
}

type EXPRESSION_NODE interface {
	NODE
	expressionNode()
}

// 二元节点
type BINARY_EXPRESSION struct {
	Operator    string
	Left, Right EXPRESSION_NODE
	Position
}

// 为BINARY_EXPRESSION实现EXPRESSION_NODE接口
func (s BINARY_EXPRESSION) expressionNode()
func (s BINARY_EXPRESSION) GetPosition() (int, int) { return s.Line, s.Column }

所以我有一个接口EXPRESSION_NODE和一个结构体BINARY_EXPRESSION,该结构体实现了接口的所有方法。

以下是我困惑的地方:

func (self *Parser) ParseBinaryExpression(
	operators []string,
	parser ExpressionParser,
) (*EXPRESSION_NODE, error) {
	self.SetPosition()
	result, err := parser()
	if err != nil {
		return nil, ChainErrs(self.Err(BINARY_EXPRESSION_ERROR), err)
	}
	for Includes(operators, self.stream.Peek().Literal) {
		operator := self.stream.Next().Literal
		right, err := parser()
		if err != nil {
			return nil, ChainErrs(self.Err(BINARY_EXPRESSION_ERROR), err)
			// 错误:无法将类型为*BINARY_EXPRESSION的&(BINARY_EXPRESSION字面量)作为*EXPRESSION_NODE类型的值进行赋值
			result = &BINARY_EXPRESSION{operator, result, right, self.position}
		}
	}
	return result, nil
}

所以这行代码:

result = &BINARY_EXPRESSION{operator, result, right, self.position}

给我报错:无法将类型为*BINARY_EXPRESSION的&(BINARY_EXPRESSION字面量)作为*EXPRESSION_NODE类型的值进行赋值

所以当我这样做时:

var a EXPRESSION_NODE = &BINARY_EXPRESSION{} 

没有使用指针时,一切都正常,但是使用指针时...
问题是我实际上需要从我的函数中返回*EXPRESSION_NODE类型的值。

英文:

I'm writing a parser in Go and I have a following code for ast construction:


type NODE interface {
	GetPosition() (int, int)
}

type EXPRESSION_NODE interface {
	NODE
	expressionNode()
}


// binary node
type BINARY_EXPRESSION struct {
	Operator    string
	Left, Right EXPRESSION_NODE
	Position
}

// implementing the EXPRESSION_NODE interface for BINARY_EXPRESSION
func (s BINARY_EXPRESSION) expressionNode()
func (s BINARY_EXPRESSION) GetPosition() (int, int) { return s.Line, s.Column }

So I have an interface EXPRESSION_NODE and BINARY_EXPRESSION struct and the struct implements all the interface methods

And here is my confusion:

func (self *Parser) ParseBinaryExpression(
	operators []string,
	parser ExpressionParser,
) (*EXPRESSION_NODE, error) {
	self.SetPosition()
	result, err := parser()
	if err != nil {
		return nil, ChainErrs(self.Err(BINARY_EXPRESSION_ERROR), err)
	}
	for Includes(operators, self.stream.Peek().Literal) {
		operator := self.stream.Next().Literal
		right, err := parser()
		if err != nil {
			return nil, ChainErrs(self.Err(BINARY_EXPRESSION_ERROR), err)
			//ERROR: cannot use &(BINARY_EXPRESSION literal) (value of type *BINARY_EXPRESSION) as *EXPRESSION_NODE value in assignment
			result = &BINARY_EXPRESSION{operator, result, right, self.position}
		}
	}
	return result, nil
}

So this line

result = &BINARY_EXPRESSION{operator, result, right, self.position}

gives me the following error: cannot use &(BINARY_EXPRESSION literal) (value of type *BINARY_EXPRESSION) as *EXPRESSION_NODE value in assignment

So when I do

var a EXPRESSION_NODE = &BINARY_EXPRESSION{} 

without pointer everything seems ok, but with pointers...
And the thing is I actually need to return *EXPRESSION_NODE from my function

答案1

得分: 2

【你的问题的翻译结果】:

通常情况下,你几乎肯定不想使用指向接口的指针。相反,你想要的是指向你的类型以实现接口的指针。

首先,确保指向你的类型的指针实现了接口:

type BINARY_EXPRESSION struct {
    Operator    string
    Left, Right EXPRESSION_NODE
    Position
}

// 注意这里使用了指针接收者
func (s *BINARY_EXPRESSION) expressionNode()
func (s *BINARY_EXPRESSION) GetPosition() (int, int) { return s.Line, s.Column }

然后,你的解析函数应该是这样的:

func (self *Parser) ParseBinaryExpression(
    operators []string,
    parser ExpressionParser,
) (EXPRESSION_NODE, error) {
    // ... 一些代码 ...
    result = &BINARY_EXPRESSION{operator, result, right, self.position}
    return result, nil
}

我建议你学习更多关于Go接口以及如何定义实现接口的方法的知识:

英文:

[The code in your question is partial, and thus the following is a sketch, not intended as full working code]

Generally, you almost certainly never want to use a pointer to an interface. What you want instead is a pointer to your type to implement an interface.

First, make sure the pointer to your type implements the interface:

type BINARY_EXPRESSION struct {
    Operator    string
    Left, Right EXPRESSION_NODE
    Position
}

// Note that pointer receivers
func (s *BINARY_EXPRESSION) expressionNode()
func (s *BINARY_EXPRESSION) GetPosition() (int, int) { return s.Line, s.Column }

And then your parse function would be something like:

func (self *Parser) ParseBinaryExpression(
    operators []string,
    parser ExpressionParser,
) (EXPRESSION_NODE, error) {
    // ... stuff ...
    result = &BINARY_EXPRESSION{operator, result, right, self.position}
    return result, nil
}

I recommend you learn more about Go interfaces and how to define methods that implement them:

huangapple
  • 本文由 发表于 2021年7月10日 23:48:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/68329276.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定