英文:
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:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论