在Elixir中如何声明全局常量?对应的最佳实践约定是什么?
Elixir 全局常量声明的最佳约定
你猜测的模块属性确实是最符合Elixir社区约定的解决方案,我们可以先从你贴的代码问题说起:
你在模块顶层直接赋值的horizontal_line变量,作用域仅局限于模块顶层,无法在def定义的函数内部直接访问,这就是你遇到编译错误的原因,换成注释里的无参数函数写法能正常运行,就是因为函数定义是模块级别的,可以在同模块的其他函数里调用。
接下来给你梳理几种常用的常量声明方式,按使用场景选择即可:
- 模块属性(最常用的模块内常量方案)
Elixir的模块属性本来就设计为可以作为模块内部的常量使用,编译期就会完成求值,不需要运行时重复计算,写法非常简洁:
如果需要把这个常量对外暴露给其他模块使用,只需要加一行对应的无参数函数导出即可:defmodule ElixirTesting do # 用@开头声明模块属性作为常量,默认仅当前模块内部可访问 @horizontal_line String.duplicate("-", 80) def test_global_constant do IO.puts(@horizontal_line) IO.puts("Console Report Section Title") IO.puts(@horizontal_line) true end end
其他模块就可以通过def horizontal_line, do: @horizontal_lineElixirTesting.horizontal_line()访问这个常量。 - 无参数函数(适合对外暴露或运行时动态计算的常量)
就是你注释里用到的写法,这种方式适合两种场景:一是常量需要对外公开访问,二是常量的值需要在运行时才能确定(比如读取应用配置、环境变量),搭配模块属性可以缓存固定值避免重复计算:defmodule ElixirTesting do # 固定值常量用模块属性缓存编译结果 @horizontal_line String.duplicate("-", 80) def horizontal_line, do: @horizontal_line # 运行时动态计算的常量直接写在函数里 def app_env, do: Application.get_env(:my_app, :run_env) end - 全局常量模块(适合跨模块共用的项目级常量)
如果有多个模块都需要用到同一个常量,建议单独创建一个常量模块统一维护所有公共常量,避免到处重复定义:
所有需要使用这些常量的模块直接调用defmodule MyApp.Const do @moduledoc "项目公共常量统一管理模块" @horizontal_line String.duplicate("-", 80) def horizontal_line, do: @horizontal_line @max_upload_size 1024 * 1024 * 10 def max_upload_size, do: @max_upload_size @default_page_size 20 def default_page_size, do: @default_page_size endMyApp.Const.xxx()即可,后续修改也只需要改这一个地方。
不推荐用进程字典、ETS这类存储来存放固定常量,完全没有必要,反而会带来额外的性能开销和状态维护问题。
内容的提问来源于stack exchange,提问作者cppProgrammer
相关产品推荐
相关产品推荐

