为什么在go常量中不允许使用“ math.Sin”?

时间:2019-03-21 20:32:20

标签: go const language-features

根据Effective Go,函数math.Sin不能用于定义常量,因为该函数必须在运行时发生。

此限制背后的原因是什么?浮点一致性? Sin实现的怪癖?还有吗?


其他语言也支持这种事情。例如,在C中:从版本4.3开始,GCC supports compile-time calculation of the sine function。 (请参见“常规优化工具的改进”部分。)

但是,如this blog post by Bruce Dawson中所述,这可能会导致意外问题。 (请参见“编译时与运行时 sin ”部分。)

这与Go相关吗?还是出于其他原因限制了此用法?

2 个答案:

答案 0 :(得分:3)

Go不支持使用函数的结果初始化常量。函数是在运行时而不是在编译时调用的。但是常量是在编译时定义的。

可能会为某些函数(例如math.Sin)设置例外,但这会使规范变得更加复杂。 Go开发人员通常希望保持规范简单一致。

答案 1 :(得分:0)

Go根本没有这个概念。无法将函数标记为纯函数(其返回值仅取决于其参数,并且不会更改任何可变状态或执行I / O),编译器无法推断 的纯正性,并且没有尝试在编译时评估包含函数调用的任何表达式(因为对除常量参数的纯函数之外的任何事情进行此操作都会产生奇怪的行为和错误,并且因为添加了机制使其正常工作所需的时间会带来很多复杂性。

是的,这是一个很大的损失,它迫使运行时行为不良的代码与丑陋的代码之间进行权衡。游击队成员会选择丑陋的代码,并告诉您您是一个不好的人,因为找不到美丽的代码。

您可以使用的最好的东西就是代码生成。将go generate集成到工具链中,并在标准库中提供完整的Go解析器,可以在构建时相对轻松地修改代码,而使用此功能可以做的一件事情是创建更高级的代码如果您愿意,可以不断折叠。您仍然会遇到代码生成的所有可调试性风险,但这就是事实。