外观
枚举
约 3377 字大约 11 分钟
高级
注意
本页面包含高级内容。如果您是 Mine Script® 编程初学者,建议先熟悉其他更基础的 Mine Script 功能,再学习本部分内容。
简介
Mine Script 枚举(又称枚举类型或 enum 类型)是一种特殊的数据类型,其所有可能值(成员)均由开发者显式定义。它通过声明一组预定义的离散值,为变量、条件表达式和集合提供更严格的值控制机制,从而增强脚本逻辑的可读性和表达力。
声明枚举
要声明枚举类型,请使用 enum 关键字并按以下语法编写:
[export ]enum <enumName>
<field_1>[ = <title_1>]
<field_2>[ = <title_2>]
...
<field_N>[ = <title_N>]枚举中的每个字段代表该枚举类型的一个唯一命名成员(值)。用户可为枚举字段指定可选的“const string”(常量字符串)标题,用于说明这些值代表的含义。如果开发者未指定字段标题,则默认使用其名称的字符串形式作为标题。[枚举输入]字段会在脚本“设置/输入”选项卡的下拉菜单中显示这些标题,脚本还可通过str.tostring()函数获取这些标题用于其他计算(更多信息请参阅下文相关章节)。
虽然上述语法看起来与声明用户自定义类型(UDT)的语法相似,但必须理解枚举类型和UDT具有不同用途。脚本使用UDT来创建包含“series”(序列)字段的对象,这些字段可存储任何指定类型的值。而枚举则是具有“simple”(简单)字段的独特分组,代表变量、表达式和集合可接受的特定预定义值,这些值都属于同一独特类型。
例如,以下代码块声明了一个包含三个字段(buy、sell 和 neutral)的 Signal 枚举类型,每个字段代表该枚举类型的唯一成员(可能值):
Mine Script®
已复制
请注意:
Signal标识符代表枚举的名称,表示字段所属的独特类型- 我们使用
//@enum和//@field注解来记录枚举及其字段的含义 - 与
buy和sell字段不同,neutral字段没有指定标题,因此其标题是其名称的字符串表示形式("neutral")
要访问枚举的成员,请使用点符号语法引用其字段名,格式如下:
Mine Script®
已复制
与其他类型一样,脚本可以将枚举成员赋值给变量、函数参数和UDT字段,从而严格控制允许的值范围。
例如,以下代码声明了一个mySignal变量,其初始值为Signal枚举的neutral成员。后续赋给该变量的任何值都必须是同一枚举类型的成员:
Mine Script®
已复制
需要注意的是,上述代码行不需要显式声明变量类型为 Signal,因为编译器可以从赋值自动推断出类型信息。但如果使用 na 作为初始值,则必须使用 Signal 类型关键字来指定 mySignal 变量将接受 Signal 枚举的成员:
Mine Script®
已复制
使用枚举
脚本可以通过==和!=运算符比较枚举成员,并在条件结构中使用它们,从而以便捷的方式创建逻辑模式,同时降低意外值或操作的风险。
以下示例声明了一个包含三个字段(rsi、mfi和cci)的OscType枚举,分别代表不同的振荡器选项。calcOscillator()函数在switch结构中使用OscType成员来确定计算哪个振荡器。脚本通过枚举输入的值作为选择参数调用该函数,并绘制计算得到的振荡器:

Mine Script®
已复制
请注意:
calcOscillator()函数的selection参数只能接受以下四个值之一:OscType.rsi、OscType.mfi、OscType.cci或 na- 脚本"设置/输入"选项卡中的"振荡器类型"输入项,其下拉菜单会显示所有
OscType字段标题。有关枚举输入的更多信息,请参阅相关章节。
必须特别注意:每个声明的枚举都代表一个独立类型。脚本不能比较不同枚举的成员,也不能在需要特定枚举类型的表达式中混用不同枚举的成员——即使这些枚举包含完全相同的字段名称和标题。
以下示例在前述脚本中新增了OscType2枚举,并将oscInput变量改为使用该枚举成员。由于calcOscillator()函数要求OscType类型参数,而传入的是OscType2成员,此时脚本会触发编译错误:
Mine Script®
已复制
枚举字段标题的运用
枚举字段的“string”标题允许开发者为每个成员添加额外信息。当调用input.enum()函数时,这些字段标题会显示在脚本“设置/输入”选项卡的下拉菜单中。
脚本也可以在计算和逻辑中使用枚举字段标题。通过对枚举字段使用字符串转换函数(str.tostring())来访问其标题。
以下示例结合不同枚举字段标题构建了一个用于从其他上下文请求数据的交易对ID。脚本声明了两个枚举Exchange和Pair,它们的字段分别代表交易所和货币对名称。它使用input.enum()将用户指定的枚举成员赋值给exchangeInput和pairInput变量,然后通过str.tostring()获取这些变量的“string”标题并将它们连接起来,形成一个“交易所:交易对”格式的字符串,用于request.security()调用:

Mine Script®
已复制
需要注意的是:
Exchange和Pair枚举的所有成员均未指定标题。因此,每个字段的标题是其名称的字符串表示形式(如脚本的枚举输入所示)。- 调用str.tostring()函数是获取枚举字段标题以进行额外计算的唯一方法。str.format()和
log.*()函数不能直接接受枚举成员。若要在字符串格式化函数中使用字段标题,需先对该字段调用str.tostring(),然后将结果字符串传递给函数。
收集枚举成员
Mine Script的集合类型(数组、矩阵和映射)可以存储枚举成员,从而严格控制集合中允许的值。要声明存储枚举成员的集合,需在集合的类型模板中包含枚举名称。
例如,以下代码块创建了一个用于存储FooBar枚举成员的空数组。该数组允许的元素值只能是FooBar.foo、FooBar.bar、FooBar.baz和na:
Mine Script®
已复制
枚举在与映射结合使用时特别有用。与其他非基础类型不同,脚本可以声明键为枚举类型的映射,从而严格控制键值对中允许的所有可能键。
以下示例使用了一个以枚举为键、“int”为值的映射,用于跟踪并统计图表上不同信号状态的出现次数。脚本中的Signal枚举包含五个字段,代表特定的命名状态。signalCounters映射在类型模板中使用Signal作为第一个关键字,指定其仅接受Signal成员作为键。
脚本使用switch结构计算signalState变量(其值为Signal枚举的成员),并据此决定更新signalCounters映射中的哪个计数器。它构建了一个“string”来表示映射的键值对,并在最后一根K线上通过单列表格显示结果:

Mine Script®
已复制
需要注意的是:
signalCounters映射最多可包含六个键值对,因为Signal枚举预定义了五个值,再加上可能的 na 值,且映射不能包含重复键。- 脚本使用 var 关键字声明
signalCounters变量,表示该映射实例在多次执行中持续存在。 - 在第一根K线上,脚本通过五次 map.put() 调用来确定
signalCounters映射中键的插入顺序。更多信息请参阅映射页面的相关章节。 - 为最小化资源消耗,脚本在第一根K线上声明
infoTable并初始化其单元格,然后在最后一根K线上更新单元格文本。
枚举命名遮蔽
为了避免未来Mine Script新增的命名空间与现有脚本中的枚举名称发生冲突,枚举名称可以遮蔽部分Mine Script的命名空间。
例如,可以声明如下枚举,其名称遮蔽了syminfo.*命名空间:
Mine Script®
已复制
但只有当枚举字段的名称不与命名空间中的任何内置函数/变量重名时,才允许使用此类枚举名称。否则,Mine 将无法确定脚本应该使用哪个值,从而导致编译错误:
Mine Script®
已复制
此外,开发者不能使用任何Mine Script内置类型名称作为枚举的名称。
注意
尽管如之前所述,某些枚举名称可以遮蔽(shadow)语言的命名空间,但我们建议尽可能为枚举选择唯一的名称,这样的代码可读性更高,也更易于维护。