0

0

如何使用Golang实现简单表达式计算_Golang基本语法操作实践

P粉602998670

P粉602998670

发布时间:2025-12-31 14:09:08

|

373人浏览过

|

来源于php中文网

原创

Go标准库无eval,用go/parser+go/constant可安全求值纯数字四则表达式,但不支持变量、函数或逻辑运算;需前置校验输入合法性,支持变量时应改用antonmedv/expr等专用引擎。

如何使用golang实现简单表达式计算_golang基本语法操作实践

Go 语言标准库没有内置表达式求值器,eval 类功能需手动实现或借助第三方包;直接用 go/parser + go/constant 可安全解析简单算术表达式,但不支持变量、函数调用或逻辑运算。

go/parsergo/constant 解析并计算纯数字表达式

这是最轻量、最安全的方案,适用于形如 "2 + 3 * 4""(10 - 2) / 2" 的整数/浮点数四则运算。它绕过字符串拼接执行,避免代码注入风险。

  • 只支持常量表达式(不能含变量、标识符、函数调用)
  • 需将输入包裹成合法 Go 表达式语句,例如加前缀 "const _ = "
  • go/parser.ParseExpr 解析 AST,再用 go/constant.Int64ValFloat64Val 提取结果
  • 整数除法会自动截断,若需浮点结果,确保至少一个操作数带小数点(如 "6.0 / 4"
package main

import ( "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 operationundefined: xxx 错误怎么办

这类错误几乎都源于输入不是合法 Go 常量表达式:

HTTPie AI
HTTPie AI

AI API开发工具

下载

立即学习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 }

真正麻烦的不是写个计算器,而是决定「哪些东西必须禁止」:用户输入是否可能含恶意构造(如超深递归、超长数字、科学计数法溢出)?是否要限制执行时间?这些边界问题比语法解析本身更消耗精力。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

174

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

224

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

335

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

206

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

193

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

188

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

191

2025.06.17

小游戏4399大全
小游戏4399大全

4399小游戏免费秒玩大全来了!无需下载、即点即玩,涵盖动作、冒险、益智、射击、体育、双人等全品类热门小游戏。经典如《黄金矿工》《森林冰火人》《狂扁小朋友》一应俱全,每日更新最新H5游戏,支持电脑与手机跨端畅玩。访问4399小游戏中心,重温童年回忆,畅享轻松娱乐时光!官方入口安全绿色,无插件、无广告干扰,打开即玩,快乐秒达!

30

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.3万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号