外观
循环
约 12675 字大约 42 分钟
简介
循环是根据指定条件重复执行代码块的结构。它们允许脚本执行重复性任务而无需重复编写代码。Mine Script®提供三种不同的循环类型:for、while和for...in。
Mine Script中的每个循环结构都由两个主要部分组成:循环头和循环体。循环头决定循环执行的条件。循环体是缩进的代码块(局部代码块),只要循环头的条件保持有效,脚本就会在每次循环迭代时执行该代码块。更多信息请参阅"通用特性"部分。
理解何时以及如何使用循环对于充分利用Mine Script的功能至关重要。低效或不必要地使用循环可能导致运行时性能不佳。然而,在必要时有效使用循环可以使脚本执行各种计算,这些计算在没有循环的情况下将不切实际或无法实现。
在不需要使用循环的情况下
Mine的执行模型和时间序列结构使得循环在许多场景中成为非必要选择。
当用户将Mine脚本添加到图表时,它会在一个相当于大型循环的环境中运行,在可用数据的每根历史K线和实时tick上执行其代码。脚本可以通过历史引用运算符访问之前K线执行时的值,而使用var 或 varip关键字声明的变量能够在多次执行间保持计算值。这些特性使脚本能够利用逐K线计算来完成各种任务,而不必依赖显式循环。
此外,诸如ta.*命名空间中的多个内置函数已进行内部优化,无需使用循环即可完成各类计算。
让我们通过一个简单示例说明Mine中不必要的循环使用场景。为计算指定数量K线的close平均值,Mine初学者可能会编写如下代码——使用for循环计算lengthInput根K线的历史值总和,再将结果除以lengthInput:

Mine Script®
已复制
在Mine中使用for循环来完成此类任务是不必要且低效的。我们可以利用执行模型和现有的内置函数来消除这种循环。下面,我们用简单的ta.sma()函数调用替换了这些计算。这段代码更简短,并且能更高效地实现相同结果:

Mine Script®
已复制
在必须使用循环的情况下
尽管Mine的执行模型、时间序列和现有内置函数通常能在多数情况下避免使用循环,但并非所有迭代任务都有无循环替代方案。以下几种情况必须使用循环:
例如,当需要识别哪些历史K线的最高价高于当前K线的最高价时,就必须使用循环,因为在脚本执行历史K线时无法获取当前值。脚本只能在执行当前K线时访问当前值,且必须在该次执行期间回溯历史序列以比较之前的值。
以下脚本使用for循环将lengthInput根历史K线的最高价与最后一根历史K线的最高价进行比较。在循环中,它调用label.new()在每个最高价超过最后一根历史K线的历史K线上方绘制圆形标签:

Mine Script®
已复制
请注意:
for循环的每次迭代都使用历史引用运算符[]来获取之前K线的最高价,其中循环计数器(i)作为历史偏移量。label.new()调用也使用该计数器来确定每个标签的x坐标。
indicator声明语句中包含max_labels_count = 500,表示脚本在图表上最多可显示500个标签。
脚本调用barcolor()来高亮显示最后一根历史K线,并在该K线的最高价处绘制一条水平线作为视觉参考。
通用特性
for、while和for...in循环语句在结构、语法和一般行为上都具有相似性。在我们深入探讨每种具体的循环类型之前,先熟悉这些共同特性
结构与语法
在任何循环语句中,程序员需定义脚本保持循环和执行迭代的条件标准(其中迭代指循环局部代码块/主体内代码的一次执行)。这些条件标准属于循环头的一部分。脚本在每次迭代前评估循环头的条件标准,仅当条件保持有效时才允许新迭代执行。当循环头条件不再有效时,脚本将退出循环并跳过循环体。
具体循环头语法因循环语句类型(for、while和for...in)而异,因为每种循环使用不同的条件标准来控制迭代。有效使用循环需要选择控制条件最适合脚本任务需求的结构。更多关于各循环语句及其控制条件的信息,请参阅下文for循环、while循环和for...in循环章节。
Mine Script中的所有循环语句都遵循以下通用语法结构:
[var_declaration =] loop_header
statements | continue | break
return_expression其中:
loop_header指循环结构的头部语句,它定义了控制迭代的条件。statements指循环体中的代码语句和表达式,即循环头下方缩进的代码块。循环体内的所有语句都属于该循环的局部作用域。continue和break是循环专用的关键字,用于控制循环迭代的流程。continue关键字指示脚本跳过当前迭代的剩余部分并继续下一次迭代。break关键字使脚本停止当前迭代并完全退出循环。更多信息请参阅相关章节。return_expression表示循环体内的最后一行代码或代码块。循环在最后一次迭代后返回该代码的结果。要使用循环返回表达式的值,需将结果赋值给变量或元组。var_declaration是可选的变量或元组声明。如果循环语句包含声明的变量或元组,则由return_expression决定赋值的值。如果头部的条件不允许循环迭代,则赋值为na。
作用域
所有需要在循环中执行的代码行必须相对于循环头缩进四个空格或一个制表符。循环头下方缩进的代码行定义了循环体。这段代码是一个局部代码块,意味着循环体内所有的定义仅在循环执行期间可访问。换句话说,循环体内的代码属于其局部作用域。
脚本可以在循环内修改和重新分配大多数来自外部作用域的变量。但是,任何在循环体内声明的变量严格属于该循环的局部作用域。脚本无法在循环的局部代码块之外访问这些变量。
请注意:
在循环头中声明的变量同样属于局部作用域。例如,在for循环中声明的计数器变量,只能在循环的局部代码块内部使用,无法在外部访问。
任何Mine循环语句的循环体都可以包含条件结构和嵌套的循环语句。当循环包含嵌套结构时,循环体中的每个结构都保持独立的局部作用域。例如,在外部循环作用域中声明的变量可以被内部循环访问,但在内部循环作用域中声明的变量则不能被外部循环访问。
以下简单示例演示了循环局部作用域的工作原理。该脚本在最后一根历史K线上通过for循环调用label.new(),在lengthInput根历史K线上方绘制标签。每个标签的颜色取决于在循环局部代码块中声明的labelColor变量,而每个标签的位置取决于循环计数器(i):

Mine Script®
已复制
在上述代码中,i和labelColor变量仅在for循环的局部作用域内可访问,无法在任何外部作用域中使用。我们在循环后添加了一个label.new()调用,使用bar_index - i作为x坐标参数,labelColor作为颜色参数。这段代码将导致编译错误,因为i和labelColor在外部作用域中都不是有效变量:
Mine Script®
已复制
关键字与返回表达式
Mine Script中的每个循环都会隐式返回一个结果。循环返回的值来自循环体内最后一个表达式或嵌套结构在最终迭代时的执行结果。当没有发生任何迭代时,循环将返回na值。只有当返回值不是void类型,并且脚本将变量或元组声明赋值给循环语句时,循环返回的结果才可用。声明的变量将保存返回表达式的值,以便在循环作用域之外的其他计算中使用。
循环返回的值可能来自最终迭代时最后写入的表达式或嵌套代码块的求值结果。然而,循环体内可以包含continue和break关键字,用于控制超出循环头指定条件的迭代流程,这也会影响返回结果。程序员通常将这些关键字包含在条件结构中,以控制在特定条件发生时迭代的行为方式。
continue关键字指示脚本跳过当前循环迭代中的剩余语句和表达式,重新评估循环头的条件,并继续下一次迭代。如果循环头的条件不允许再次迭代,脚本将退出循环。
break关键字指示脚本完全停止循环并立即退出,不允许任何后续迭代。在中断循环后,脚本将跳过循环体内的所有剩余代码,并不再重新评估循环头的条件。
如果循环因continue或break关键字而提前停止,它将返回脚本最后一次对返回表达式求值的迭代结果。如果脚本在循环的任何迭代中都没有对返回表达式求值,则循环返回na结果。
这是一个示例,它在最后一根历史K线上选择性地在label中显示array中的数字。它使用for...in循环遍历数组元素并构建一个"字符串"作为显示文本。循环体内包含一个if语句,用于控制特定迭代的流程。如果当前迭代的数字是8,脚本会立即使用break关键字退出循环。否则,如果数字是偶数,它会使用continue关键字跳过当前迭代的剩余部分并进入下一次迭代。
如果上述if语句的条件均不满足,脚本将执行循环体内的最后一个表达式(即返回表达式),该表达式将当前number转换为字符串并与tempString值拼接。循环终止后,将返回此表达式最后一次求值的结果。脚本将该返回值赋给finalLabelText变量,并在label.new()调用中将其用作text参数:

Mine Script®
已复制
请注意:
label仅显示array中的奇数,因为当循环迭代的数字为偶数时,脚本不会重新分配tempString的值。但是,标签中不包含数组中的最后一个奇数(15),因为当number == 8时循环停止,导致无法遍历剩余的randomArray元素。
当脚本由于break关键字退出循环时,循环的返回值将来自tempString重新赋值表达式的最后一次求值结果。在本例中,该代码最后一次执行是在number == 9的迭代中。
for循环
for循环创建计数控制循环,该循环使用计数器变量在定义的迭代次数内管理其局部代码块的执行。
Mine Script 使用以下语法定义 for 循环:
[var_declaration =] for counter = from_num to to_num [by step_num]
statements | continue | break
return_expression其中以下部分定义了循环头:
counter表示循环每次迭代后其值都会增加的变量。from_num确定counter变量的初始值,即第一次迭代的值。to_num确定counter变量的最终值,即循环头允许新一轮迭代的循环计数器的最大值。循环会将该counter值递增一个固定值,直到达到或超过该值。step_num是值在每次迭代后counter增加或减少的量,直到达到或超过to_num。此值的指定是可选的。默认值为 1。
请参阅上文通用特性章节,详细了解循环语法中的以下部分 var_declaration(变量声明)、statements(语句)、continue、break 以及 return_expression(返回表达式)。
这个简单的脚本演示了在最后一根历史K线上执行时,通过for循环在未来多根K线位置绘制标签的功能:

Mine Script®
已复制
请注意:
i变量代表循环计数器。该变量属于循环的局部作用域,意味着外部作用域无法访问它。代码在循环体内使用该变量来确定每个标签绘制的位置和文本内容。- 程序员通常使用
i、j和k作为循环计数器标识符。但任何有效的变量名都可以使用。例如,如果我们将计数器命名为level而不是i,这段代码的行为将完全相同。 - for循环结构自动管理计数器变量。我们不需要在循环体内编写代码来递增其值。
- 循环头指定计数器在脚本进入循环时从0开始,每次迭代后其值增加1,直到达到10(此时执行最后一次迭代)。换句话说,循环总共会执行11次迭代。
for循环的局部代码块会重复执行,直到其计数器变量的值达到指定的to_num边界值。计数器的定义边界和步长直接控制循环的迭代次数。因此,脚本在循环开始前就能确定预期的迭代次数。正因如此,for循环最适合用于那些最大迭代次数可预先确定的迭代任务。
下面的示例计算并绘制了开盘价的成交量加权移动平均线(VWMA),范围覆盖maLengthInput指定的K线数量。该脚本在最后一根历史K线上使用for循环分析当前vwmaOpen值与过去vwmaOpen值之间的差异。在每次循环迭代中,脚本会获取之前一根K线的vwmaOpen值,计算该值与当前vwmaOpen的差值,并将结果显示在对应历史K线的开盘价位置的标签中:

Mine Script®
已复制
请注意:
- 脚本在循环体内使用循环计数器
i结合历史引用操作符获取vwmaOpen序列的历史值,并利用该计数器确定每个标签的绘制位置。 - 循环计数器的值从
lookbackInput开始,每次迭代递减 1,直至i == 1。
开发者可以使用 for 循环来遍历集合((数组和矩阵),其中循环计数器可作为索引来访问或修改集合元素。例如,以下代码块在 for 循环中使用 array.get() 方法逐个获取数组元素:
Mine Script®
已复制
请注意:
- 数组索引从0开始,但array.size()函数计算的是元素数量(即从1开始计数)。因此,我们必须从数组大小中减去1才能获得最大索引值。这样,循环计数器在最后一次循环迭代时就不会表示超出数组边界的索引。
- for...in循环语句通常是遍历集合的首选方式。但在某些情况下,程序员可能更倾向于使用for循环,例如:遍历步进索引值、以反向或非线性顺序迭代集合内容等。有关遍历这些集合类型的最佳实践,请参阅"遍历数组"和"遍历矩阵"章节。
以下脚本计算收盘价在三个不同周期长度(10、20 和 50)上的 RSI 和动量指标,并在最后一根 K 线上以表格形式显示其数值。脚本将表头标题的"字符串"值存储在数组中,将计算所得指标的"浮点数"值存储在 2x3 矩阵中。脚本首先使用 for 循环访问数组元素并初始化displayTable表头单元格,随后通过嵌套 for 循环遍历 taMatrix 的行列索引来访问矩阵元素,将其值转换为字符串并填充表格其余单元格:

Mine Script®
已复制
请注意:
- 两个表头名称数组(
sideHeaderTitles和topHeaderTitles)包含相同数量的元素,这使我们能够使用单个for循环同时遍历它们的内容。 - 嵌套的for循环遍历
taMatrix中的所有索引值。外部循环遍历每个行索引,内部循环在每次外部循环迭代时遍历每个列索引。 - 脚本仅在最后一根历史K线和所有实时K线上创建并显示表格,因为表格的历史状态永远不可见。
while循环
while循环创建条件控制循环,该循环使用条件表达式来控制其局部代码块的执行。只要条件表达式保持为true,循环就会继续迭代。
Mine Script 使用以下语法定义 while 循环:
[var_declaration =] while condition
statements | continue | break
return_expression其中,循环头中的condition可以是返回"bool"类型值的字面量、变量、表达式或函数调用。
有关循环语法中var_declaration(变量声明)、statements(语句)、continue、break和return_expression(返回表达式)各部分的详细信息,请参阅前文通用特性章节。
while循环头在每次迭代前都会重新评估其条件。因此,当脚本在迭代内部修改条件时,循环头将在下一次迭代中反映这些变化。
根据循环头中指定的条件,while循环的行为可以类似于for循环,持续迭代直到计数器变量达到指定限制。例如,以下脚本使用for循环和while循环执行相同的任务。两个循环在每次迭代时都会绘制一个显示各自计数器值的标签:

Mine Script®
已复制
请注意:
- 当while循环使用基于计数的逻辑时,必须在局部代码块内显式管理用户指定的计数器。相比之下,for循环会自动递增其计数器。
- 脚本在循环作用域外部声明while循环使用的计数器变量,这意味着该变量的值在循环终止后仍可用于其他计算。
- 如果此代码没有在while循环体内递增
j变量,其值将永远不会达到10,这意味着循环将无限运行,直到导致运行时错误。
由于while循环的执行依赖于其条件保持为true,且该条件在特定迭代中可能不会改变,因此与for循环不同,在循环开始前可能无法预知确切的迭代次数。因此,while循环在循环边界未知的情况下更具优势。
以下脚本跟踪当图表收盘价突破用户指定长度和通道宽度的 Keltner Channels 时的情况。当价格突破当前K线的通道时,脚本会绘制一个box,高亮显示所有先前收盘价在该价格窗口内的连续K线。脚本使用while循环分析过去K线的价格,并逐步调整每个新box的左侧边界,直到绘制覆盖当前范围内所有最新的连续K线。
在此场景中必须使用while循环,因为当前K线的通道值无法预先确定,且无法预测需要多少次迭代才能包含通道范围内的所有连续K线:

Mine Script®
已复制
请注意:
- 方框的左右边缘位于各自对应K线的水平中心位置,这意味着每个绘制区域从第一根连续K线的中心延伸至该区域内最后一根K线的中心。
- 该脚本在while循环每次迭代检查的条件表达式中,将
i变量作为历史引用索引使用。该变量不充当循环计数器(因迭代边界未知)。循环持续执行其局部代码块,直到条件变为false。
for...in循环
for...in循环创建集合控制循环,该循环通过集合的内容来控制其迭代。这种循环结构通常是遍历数组、矩阵和映射的首选方法。
for...in循环按顺序遍历集合,在每次迭代时检索其中一个存储项。因此,循环的边界直接取决于集合的项数(array元素、matrix行或map键值对)。与for循环类似,脚本在for...in循环开始前即可确定预期的迭代次数。
Mine Script 提供了两种通用形式的 for...in 循环语句。第一种形式使用以下语法:
[var_declaration =] for item in collection_id
statements | continue | break
return_expression其中,item 是一个变量,用于依次存储指定 collection_id 中的值。该变量的值从集合的第一个元素开始,每次迭代后按顺序获取下一个元素。当脚本需要迭代访问array或matrix中的值,但不需要在计算中使用元素的索引时,这种形式非常方便。
第二种形式的语法略有不同,其头部包含一个元组:
[var_declaration =] for [index, item] in collection_id
statements | continue | break
return_expression其中,index 是包含检索项索引/键名的变量,item 是该项的对应值。当迭代计算中需要同时使用集合元素及其索引/键名时,此形式非常实用。遍历映射(map)时必须使用此形式的for...in循环,更多信息请参阅相关章节。
请参阅前文通用特性章节,了解循环语法中以下部分的详细信息:var_declaration(变量声明)、statements(语句)、continue、break和return_expression(返回表达式)。
for...in循环的迭代行为取决于循环头中collection_id指定的集合类型:
- 当在循环头中使用array时,循环执行元素级迭代,即每次迭代获取的是数组的一个元素。
- 当在循环头中使用matrix时,循环执行行级迭代,即每次迭代获取的是代表矩阵行的数组。
- 当在循环头中使用map时,循环执行键值对迭代,即每次迭代获取一个键和对应的值。
遍历数组
Mine脚本可以使用任何循环结构来遍历数组元素。不过,for...in循环通常是最便捷的选择,因为它在控制迭代时会自动验证array大小。使用其他循环结构时,程序员必须仔细设置循环头的边界或条件,以防止循环尝试访问不存在的索引元素。
例如,开发者可以使用for循环,通过将计数器变量作为array.get()等函数的查找索引来访问数组元素。但为防止越界错误,必须确保计数器始终代表有效索引。此外,若数组可能为空,需设置条件完全阻止循环执行。
以下代码展示了一个计数器边界取决于数组元素数量的for循环。若数组为空(含0个元素),循环头的最终计数器值为na,从而阻止迭代;否则最终值为数组size减一(即最后一个元素的索引):
Mine Script®
已复制
相比之下,for...in循环能自动验证数组大小并直接访问其元素,相比传统for循环提供了更便捷的解决方案。以下代码行即可实现与上述代码相同的效果,且无需开发者显式定义边界或使用array.get()函数来访问每个元素:
Mine Script®
已复制
以下示例通过分析低时间周期K线来评估每根主周期K线内的趋势强度。该脚本使用request.security_lower_tf()函数获取来自lowerTimeframe的hl2价格数组,随后通过for...in循环遍历intrabarPrices数组中的每个价格,并将其与当前收盘价比较以计算K线strength。最终将strength值以柱状图形式绘制在独立面板中:

Mine Script®
已复制
当脚本计算需要同时访问数组元素及其对应索引时,for...in循环的第二种形式提供了便捷的解决方案:
Mine Script®
已复制
例如,假设我们需要在标签中显示数组元素的编号列表,同时排除特定索引处的值。我们可以使用for...in循环的第二种形式来完成此任务。以下简单脚本声明了一个stringArray变量,引用预定义的"字符串"值数组。在最后一根历史K线上,脚本使用for...in循环访问stringArray中的每个index和element来构建labelText,并在循环结束后将其用于label.new()调用:

Mine Script®
已复制
请注意:
- 此示例在str.tostring()调用中将索引加1,使编号列表从"1"开始显示,因为数组索引总是从0开始。
- 在第三次循环迭代中,当
index == 2时,脚本会在labelText中添加"ELEMENT SKIPPED"消息而不是检索到的element,并使用continue关键字跳过该迭代的剩余部分。有关循环关键字的更多信息,请参阅前文相关章节。
让我们探讨一个展示for...in循环实用性的高级示例。以下指标在计算得出的枢轴高点位置绘制固定数量的水平线,并通过循环分析这些线以确定哪些代表有效(未被突破)的枢轴点。
每当脚本检测到新的枢轴高点时,它会创建一条新水平线,将该线插入pivotLines数组开头,然后移除最旧元素并删除其ID。脚本通过for...in循环访问数组中的每条水平线,在每次迭代中分析并修改获取的pivotLine属性。当当前高点突破pivotLine时,脚本改变其样式以标记其失效;否则,脚本延长该线的x2坐标并使用其价格计算有效枢轴的平均值。脚本同时绘制每个枢轴高点和有效枢轴平均值作为视觉参考:

Mine Script®
已复制
请注意:
- 该示例中的循环在每根K线上执行,因为它需要将每个有效
pivotLine的价格与当前最高价进行比较,并使用这些价格计算每根K线的avgActivePivot值。 - Mine Script提供了多种计算平均值的方法,其中许多不需要使用循环。但在本示例中必须使用循环,因为脚本需要使用仅在当前K线上可用的信息来确定哪些价格参与平均值计算。
- 在此示例中,for...in循环的第一种形式是最方便的选择,因为我们需要直接访问
pivotLines数组中的线条,但不需要对应的索引值。
遍历矩阵
Mine脚本可通过多种方式遍历矩阵内容。与数组不同,矩阵采用行列双索引结构(第一个索引为行号,第二个为列号)。若开发者选择使用for或while循环(而非for...in)遍历矩阵,必须精确定义循环边界以防越界错误。
以下代码展示通过for循环执行行级迭代,遍历矩阵的每个行索引,并通过matrix.row()获取行数组。若矩阵为空,循环终止值设为na阻止执行;否则终止值为行数减1(即末行索引):
Mine Script®
已复制
请注意:
- 若将代码中的matrix.rows()和matrix.row()调用替换为matrix.columns()和matrix.col(),循环将执行列级迭代而非行级迭代。
for...in循环是更便捷的矩阵行遍历方案,它能自动验证行数并在每次迭代时获取当前行元素的数组:
Mine Script®
已复制
当脚本计算需要同时访问矩阵的行数据及其对应索引时,开发者可采用for...in循环的第二种形式:
Mine Script®
已复制
请注意:
以下示例展示了一个自定义"字符串",用于表示矩阵各行及其附加信息,并通过标签显示。当脚本在最后一根历史K线上执行时,它会创建一个3x3的随机矩阵randomMatrix,并用随机值填充。随后,脚本使用for...in循环的第一种形式遍历randomMatrix中的每一行,创建一个表示该行内容、平均值以及平均值是否大于0.5的"字符串",并将该"字符串"与labelText拼接。循环结束后,脚本创建一个标签显示labelText值:

Mine Script®
已复制
矩阵操作通常需要迭代访问其元素(而不仅仅是行或列),这通常需要使用嵌套循环。例如,以下代码块使用外部for循环遍历行索引,内部for循环在每次外部循环迭代时遍历列索引,并通过matrix.get()访问元素:
Mine Script®
已复制
更便捷的做法是使用嵌套的for...in循环来完成此类任务。此代码块中的外层for...in循环获取矩阵中的每个行数组,而内层for...in语句则遍历该数组:
Mine Script®
已复制
以下脚本创建一个3x2矩阵,并在嵌套的for...in循环中访问和修改其元素。两个循环都使用for...in语句的第二种形式来获取索引值和对应项。外层循环从矩阵中获取行索引和行数组,内层循环从该数组中获取每个索引和相应元素。
在嵌套循环的迭代中,脚本将每个element转换为"字符串"并在rowIndex行colIndex列初始化一个表格单元格。随后,脚本在matrix.set()中使用循环头变量更新矩阵元素。在外层循环结束后,脚本在标签中显示更新后矩阵的"字符串"表示形式:

Mine Script®
已复制
遍历映射
for...in循环语句是遍历Mine Script映射中数据的主要且最便捷的方式。
与数组和矩阵不同,映射是无序集合,以键值对形式存储数据。脚本通过引用映射中的键来访问其值,而不是通过内部查找索引遍历。因此,在遍历映射时,脚本必须执行键值对迭代,这意味着在迭代过程中获取的是键值对,而不是索引元素或行。
请注意:
- 虽然映射是无序集合,但Mine Script内部会跟踪其键值对的插入顺序。
访问映射(Map)数据的一种方式是使用map.keys()函数,该函数返回一个包含映射中所有键的数组,按键的插入顺序排序。脚本可以使用for...in结构遍历数组,并通过map.get()获取对应的值:
Mine Script®
已复制
但更便捷且推荐的做法是直接遍历映射(Map),而无需创建新数组。要直接遍历映射,请使用for...in循环的第二种形式。将此循环与映射一起使用时,每次迭代都会创建一个包含键和对应值的元组。与遍历map.keys()数组时类似,这种直接的for...in循环会按照键值对的插入顺序进行迭代:
Mine Script®
已复制
请注意:
- for...in循环的第二种形式是直接遍历映射(Map)的唯一方式。脚本在遍历此集合类型时,必须通过每次迭代同时获取键和值,无法仅单独遍历键或值。
让我们看一个演示for...in循环如何操作映射(Map)的简单示例。当以下脚本在最后一根历史K线上执行时,它会声明一个simpleMap变量,并为其分配一个包含"字符串"键和"浮点数"值的映射。脚本将newKeys数组中的键与对应的随机值存入该集合。然后使用for...in循环遍历simpleMap中的键值对来构建displayText。循环结束后,脚本在标签中显示displayText以可视化结果:

Mine Script®
已复制
请注意: