Go编写AST解析器时*BINARY_EXPRESSION无法赋值给*EXPRESSION_NODE报错
报错原因
Go语言中,接口类型本身自带引用语义,指向接口的指针*EXPRESSION_NODE和接口本身EXPRESSION_NODE是完全不同的两个类型:
- 你的
*BINARY_EXPRESSION实现的是EXPRESSION_NODE接口,而非*EXPRESSION_NODE类型,因此无法直接赋值给类型为*EXPRESSION_NODE的变量 - 你测试的
var a EXPRESSION_NODE = &BINARY_EXPRESSION{}语句可以正常运行,正是因为你赋值给的是接口类型本身,而非接口指针,符合类型匹配规则
另外你当前代码存在逻辑错误:result = &BINARY_EXPRESSION{...}写在了if err != nil分支的return语句之后,这行代码原本就永远不会被执行。
解决方案
推荐方案:移除不必要的接口指针
Go中几乎不存在需要使用「指向接口的指针」的场景,直接修改函数返回值为接口本身即可:
// 把返回值类型从 *EXPRESSION_NODE 改为 EXPRESSION_NODE 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) } // 这行赋值移到if err判断外,此时类型匹配不会报错 result = &BINARY_EXPRESSION{operator, result, right, self.position} } return result, nil }
兼容方案(不推荐):强制转成接口指针
如果因为其他依赖必须保留*EXPRESSION_NODE返回值,可以先把结构体指针赋值给接口变量,再取接口变量的地址:
var expr EXPRESSION_NODE = &BINARY_EXPRESSION{operator, result, right, self.position} result = &expr
该方案仅做兼容,没有任何实际收益,不建议使用。
内容的提问来源于stack exchange,提问作者4nnihil4tor
相关产品推荐
相关产品推荐

