Почему `math.Sin` не разрешен в константе Go? - PullRequest
0 голосов
/ 21 марта 2019

Согласно Effective Go , функция math.Sin не может использоваться для определения константы, потому что эта функция должна выполняться во время выполнения.

Что является причиной этого ограничения?Согласованность с плавающей точкой?Причуды реализации Sin?Что-то еще?


Существует поддержка такого рода вещей на других языках.Например, в C: начиная с версии 4.3, GCC поддерживает вычисление синусоидальной функции во время компиляции.(См. Раздел «Общие улучшения оптимизатора»).

Однако, как отмечено в этом сообщении в блоге Брюса Доусона , это может вызвать неожиданные проблемы.(См. Раздел «Время компиляции против времени выполнения sin »).

Это актуальная проблема в Go?Или это использование ограничено по другой причине?

Ответы [ 2 ]

3 голосов
/ 21 марта 2019

Go не поддерживает инициализацию константы с результатом функции. Функции вызываются во время выполнения, а не во время компиляции. Но константы определяются во время компиляции.

Можно было бы сделать исключения для определенных функций (например, math.Sin), но это усложнило бы спецификацию. Разработчики Go обычно предпочитают, чтобы спецификация была простой и последовательной.

0 голосов
/ 21 марта 2019

Go просто не хватает концепции. Нет способа пометить функцию как чистую (ее возвращаемое значение зависит только от ее аргументов, и она не изменяет какого-либо изменяемого состояния или не выполняет ввод / вывод), для компилятора нет способа сделать вывод чистоты, и нет никакой попытки оценить какое-либо выражение, содержащее вызов функции во время компиляции (потому что выполнение этого для чего-либо, кроме чистой функции с постоянными аргументами, будет источником странного поведения и ошибок, и потому что добавление необходимого механизма чтобы заставить его работать правильно, пришлось бы немножко усложнить).

Да, это существенная потеря, которая вызывает компромисс между кодом с плохим поведением во время выполнения и кодом, который выглядит ужасно. Иди партизаны выберут уродливый код и скажут, что ты плохой человек, потому что не находишь его красивым.

Лучшее, что у вас есть, - это генерация кода. Интеграция go generate в набор инструментов и предоставление полного синтаксического анализатора Go в стандартной библиотеке позволяет относительно легко разбирать код во время сборки, и одна из возможностей, которую вы можете сделать с помощью этой возможности, - создать более продвинутые константы - складной, если вы того пожелаете. Вы по-прежнему получаете всю опасность отладки генерации кода, но это что-то.

...