外观
对象
约 2653 字大约 9 分钟
高级
注意
本页面包含高级内容。如果您是 Mine Script® 编程初学者,建议先熟悉其他更基础的 Mine Script 功能,再学习本部分内容。
简介
Mine Script 中的对象是用户自定义类型(UDT)的实例。它们相当于包含多个字段的变量,每个字段都能存储独立的值,这些值可以是不同类型。
有经验的程序员可以将 UDT 理解为没有方法的类。它们允许用户创建自定义类型,将不同的值组织在一个逻辑实体下。
创建对象
在使用对象之前,必须先定义其类型。具体类型定义方法请参阅类型系统章节中的用户自定义类型部分。
以下定义一个用于存储枢轴点信息的 pivotPoint 类型:
Mine Script®
已复制
请注意:
- 我们使用 type 关键字声明创建 UDT。
- 我们将新的 UDT 命名为
pivotPoint。 - 在第一行之后,我们创建一个包含每个字段类型和名称的局部块。
x字段将保存枢轴点的x坐标。它被声明为 "int" 类型,因为它将保存时间戳或 "int" 类型的柱线索引。y是 "float" 类型,因为它将保存枢轴点的价格。xloc是一个字段,用于指定x的单位:xloc.bar_index 或 xloc.bar_time。我们使用=运算符将其默认值设为 xloc.bar_time。当从该 UDT 创建对象时,其xloc字段将被设置为该默认值。
现在我们已经定义了 pivotPoint UDT,接下来可以通过该类型的 new() 内置方法创建对象实例。要基于 pivotPoint 类型创建 foundPoint 对象,使用以下语法:
Mine Script®
已复制
我们还可以通过以下方式为创建的对象指定字段值:
Mine Script®
已复制
或者使用等效的简洁语法:
Mine Script®
已复制
此时,foundPoint 对象的 x 字段将包含创建时 time 内置变量的值,y 字段将包含 high 的值,而 xloc 字段将保持其默认值 xloc.bar_time(因为在创建对象时未指定该字段的值)。
也可以通过以下方式声明空对象占位符(使用 na 初始化):
Mine Script®
已复制
这个示例会在检测到高点枢轴时显示标签。由于枢轴点需要在发生 legsInput 根K线后才能被检测到,因此我们需要在过去的位置绘制标签,使其显示在枢轴点上:
Mine Script®
已复制
特别注意上例中的这一行代码:
Mine Script®
已复制
这也可以使用以下方式编写:
Mine Script®
已复制
当使用 var 关键字声明一个用户自定义类型(UDT)对象变量时,该关键字会自动应用于对象的所有字段:
Mine Script®
已复制
需要特别注意:当把对象赋值给使用 varip 关键字的变量时,不会自动使对象的所有字段在每次实时K线更新时避免回滚。必须在该类型的声明中为每个需要此特性的字段单独添加 varip 关键字才能实现此行为。例如:
Mine Script®
已复制
请注意:
- 我们使用 var 关键字指定分配给
counter变量的Counter对象在整个脚本执行期间持续存在。 bars字段会在实时 K 线上回滚,而ticks字段不会回滚,因为我们在其声明中包含了 varip。
更改字段值
对象字段的值可以通过 := 重新赋值运算符进行修改。
在我们之前的示例中,这行代码:
Mine Script®
已复制
也可以使用以下方式编写:
Mine Script®
已复制
对象集合操作
Mine Script的集合类型(数组、矩阵和映射)可以存储对象,这为数据结构添加了虚拟维度。要声明对象集合,需将用户自定义类型(UDT)名称传入集合的类型模板。
这个示例声明了一个用于存储 pivotPoint 用户自定义类型对象的空数组:
Mine Script®
已复制
要显式声明一个变量为"用户自定义类型"的数组、矩阵或映射,请使用集合的类型关键字后跟其类型模板。例如:
Mine Script®
已复制
让我们运用所学知识创建一个检测高点枢轴的脚本。该脚本首先将历史枢轴点信息收集到数组中,然后在最后一根历史K线上遍历数组,为每个枢轴点创建标签并用连线连接它们:

Mine Script®
已复制
复制对象
在Mine Script中,对象是通过引用赋值的。当把现有对象赋值给新变量时,两者将指向同一个对象。
在以下示例中,我们创建了一个pivot1对象并将其x字段设为1000。然后声明了一个包含pivot1对象引用的pivot2变量,因此两者指向同一实例。修改pivot2.x也会同时改变pivot1.x,因为它们都引用同一对象的x字段:
Mine Script®
已复制
要创建独立于原对象的副本,可以使用内置的 copy() 方法。
在这个示例中,我们声明 pivot2 变量引用 pivot1 对象的副本。此时修改 pivot2.x 不会改变 pivot1.x,因为它们现在引用的是两个独立的对象:
Mine Script®
已复制
需要特别注意的是,内置的 copy() 方法生成的是对象的浅拷贝。如果对象的字段包含特殊类型(array, matrix, map, line, linefill, box, polyline, label, table 和 chart.point),这些字段在浅拷贝对象中仍会指向与原始对象相同的实例。
在以下示例中,我们定义了一个包含标签字段的 InfoLabel 类型。脚本实例化了父对象的浅拷贝,然后调用用户定义的 set() 方法来更新每个对象的 info 和 lbl 字段。由于两个对象的 lbl 字段指向同一个标签实例,任一对象对该字段的修改都会影响另一个对象:
Mine Script®
已复制
要生成一个包含所有特殊类型字段独立实例的深拷贝对象,必须显式复制这些字段。
在以下示例中,我们定义了一个 deepCopy() 方法,该方法会实例化一个新的 InfoLabel 对象,并将其 lbl 字段指向原始对象字段的副本。这样对深拷贝对象 lbl 字段的修改不会影响父对象,因为它们指向不同的实例:
Mine Script®
已复制
命名遮蔽
为避免未来Mine Script新增的命名空间与现有脚本中的用户自定义类型(UDT)或对象名称发生冲突,根据规则,UDT和对象名称会遮蔽语言的命名空间。例如,UDT或对象可以使用内置类型的名称,如line或table。