如何使用Golang实现简单表达式计算_Golang基本语法操作实践
发布时间 - 2025-12-31 00:00:00 点击率:次Go标准库无eval,用go/parser+go/constant可安全求值纯数字四则表达式,但不支持变量、函数或逻辑运算;需前置校验输入合法性,支持变量时应改用antonmedv/expr等专用引擎。
Go 语言标准库没有内置表达式求值器,eval 类功能需手动实现或借助第三方包;直接用 go/pa +
rsergo/constant 可安全解析简单算术表达式,但不支持变量、函数调用或逻辑运算。
用 go/parser 和 go/constant 解析并计算纯数字表达式
这是最轻量、最安全的方案,适用于形如 "2 + 3 * 4" 或 "(10 - 2) / 2" 的整数/浮点数四则运算。它绕过字符串拼接执行,避免代码注入风险。
- 只支持常量表达式(不能含变量、标识符、函数调用)
- 需将输入包裹成合法 Go 表达式语句,例如加前缀
"const _ = " -
go/parser.ParseExpr解析 AST,再用go/constant.Int64Val或Float64Val提取结果 - 整数除法会自动截断,若需浮点结果,确保至少一个操作数带小数点(如
"6.0 / 4")
package mainimport ( "fmt" "go/ast" "go/parser" "go/token" "go/constant" )
func evalExpr(s string) (float64, error) { expr, err := parser.ParseExpr("const _ = " + s) if err != nil { return 0, err }
// 确保是二元运算或字面量 tv, err := ast.EvalExpr(token.NewFileSet(), nil, expr) if err != nil { return 0, err } switch tv.Kind() { case constant.Int: return constant.Int64Val(tv.Value), nil case constant.Float: return constant.Float64Val(tv.Value), nil default: return 0, fmt.Errorf("unsupported constant kind: %v", tv.Kind()) }}
func main() { result, _ := evalExpr("2 + 3 * 4") fmt.Println(result) // 14 }
遇到
invalid operation或undefined: xxx错误怎么办这类错误几乎都源于输入不是合法 Go 常量表达式:
-
undefined: x→ 表达式里写了变量名(如"x + 1"),而go/parser不做变量绑定 -
invalid operation: operator + not defined on string→ 输入含未加引号的字符串字面量(如"hello + world"),应只传数字和运算符 -
syntax error: unexpected newline→ 字符串含换行或注释,需提前清理(strings.TrimSpace+ 去掉//和/* */) - 空字符串或只有空格 →
ParseExpr直接返回语法错误,建议前置校验len(strings.TrimSpace(s)) == 0
需要支持变量时,别硬改 go/parser,换用 antonmedv/expr
go/parser 天然不支持运行时变量代入,强行在 AST 上做符号表替换极易出错且破坏类型安全。更现实的做法是引入轻量表达式引擎:
-
github.com/antonmedv/expr支持变量、布尔逻辑、比较、基础函数(len,round),语法接近 Go 但更宽松 - 它仍不执行任意代码(无
exec、无反射调用),安全性可控 - 性能比
go/parser略低,但对千次/秒以下的计算场景无感 - 注意:默认禁止访问结构体字段(如
user.Name),需显式启用expr.Env并传入允许的字段名列表
import (
"fmt"
"github.com/antonmedv/expr"
)
func main() {
env := map[string]interface{}{"a": 5, "b": 3}
code := "a * b + 2"
program, := expr.Compile(code)
output, := expr.Run(program, env)
fmt.Println(output) // 17
}
真正麻烦的不是写个计算器,而是决定「哪些东西必须禁止」:用户输入是否可能含恶意构造(如超深递归、超长数字、科学计数法溢出)?是否要限制执行时间?这些边界问题比语法解析本身更消耗精力。
# git
# go
# github
# golang
# ai
# switch
# 标准库
# String
# 常量
# 运算符
# Error
# 标识符
# const
# 字符串
# 结构体
# 递归
# operator
# len
# undefined
# 但不
# 这是
# 浮点
# 求值
# 适用于
# 执行时间
# 这类
# 布尔
# 写了
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
高防服务器租用如何选择配置与防御等级?
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
利用 Google AI 进行 YouTube 视频 SEO 描述优化
简单实现Android验证码
如何在宝塔面板创建新站点?
如何快速搭建个人网站并优化SEO?
昵图网官方站入口 昵图网素材图库官网入口
想要更高端的建设网站,这些原则一定要坚持!
如何用景安虚拟主机手机版绑定域名建站?
大连网站制作公司哪家好一点,大连买房网站哪个好?
如何在VPS电脑上快速搭建网站?
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
C++时间戳转换成日期时间的步骤和示例代码
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
如何快速上传建站程序避免常见错误?
如何制作一个表白网站视频,关于勇敢表白的小标题?
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
制作旅游网站html,怎样注册旅游网站?
详解MySQL数据库的安装与密码配置
长沙做网站要多少钱,长沙国安网络怎么样?
详解Android图表 MPAndroidChart折线图
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
文字头像制作网站推荐软件,醒图能自动配文字吗?
iOS中将个别页面强制横屏其他页面竖屏
Laravel如何配置Horizon来管理队列?(安装和使用)
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
济南网站建设制作公司,室内设计网站一般都有哪些功能?
Laravel如何实现邮件验证激活账户_Laravel内置MustVerifyEmail接口配置【步骤】
Laravel如何实现本地化和多语言支持?(i18n教程)
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
javascript中闭包概念与用法深入理解
油猴 教程,油猴搜脚本为什么会网页无法显示?
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
微信h5制作网站有哪些,免费微信H5页面制作工具?
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明
Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】
如何在IIS7中新建站点?详细步骤解析
Laravel如何创建自定义中间件?(Middleware代码示例)
香港服务器如何优化才能显著提升网站加载速度?
Laravel如何配置任务调度?(Cron Job示例)
香港服务器租用每月最低只需15元?
Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率
Android中AutoCompleteTextView自动提示
Laravel怎么实现模型属性的自动加密
微信小程序 配置文件详细介绍
Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】

