连接检查

连接检查会限制哪些连接(及其块)可以连接 相互通信。

连接检查对于建模类型非常有用。例如,以下 三个块并没有被连接在一起,因为它们代表 会返回不同的类型:

一个空列表块,与平方根块连接,并连接到
大写方块

连接检查可用于阻止这些块进行连接。这个 可为用户提供即时反馈,并防止许多简单的错误。

运作方式

每个连接都可以与“连接检查”关联它是一个可为 null 的 字符串数组。

在下列情况下,两个连接可以连接:

  1. 它们是兼容的类型(例如,连接到 输入)。
  2. 它们的连接检查中至少有一个共同的字符串。

例如,以下两个检查可以连接,因为它们共享 'apple' 字符串:

['apple', 'ball', 'cat']
['apple', 'bear', 'caterpillar']

但这两项检查无法连接,因为它们不共享任何字符串:

['apple', 'ball', 'cat']
['ape', 'bear', 'caterpillar']

还有一种特殊情况。如果任一数组为 null,则 连接和连接。这样,您就可以定义 做任何事。

null
['ape', 'bear', 'caterpillar]

设置检查

默认情况下,所有连接都有 null 连接检查,这意味着它们可以 连接到任何设备连接检查需要手动分配。

为连接分配连接检查的方式因具体情况而异 使用 JSON 块定义还是 JavaScript 块定义

JSON

对于顶级关联,您可以将检查直接分配给 定义了连接。您分配的值可以是 null、一个字符串( 成为连接检查中的唯一条目),也可以是字符串数组。

{
  'type': 'custom_block',

  'output': null,
  'nextStatement': 'a connection check entry',
  'previousStatement': ['four', 'connection', 'check', 'entries']
}

对于输入,您可以将检查分配给输入的 check 属性 定义。如果 check 属性不存在,则考虑检查 null。您分配的值可以是字符串,也可以是字符串数组。

{
  'type': 'custom_block',
  'message0': '%1 %2',

  'args0': [
    {
      'type': 'input_value',
      'check': 'a connection check entry'
    },
    {
      'type': 'input_statement',
      'check': ['four', 'connection', 'check', 'entries']
    }
  ]
}

JavaScript

对于顶级连接,您可以直接将检查传递给 定义了连接。如果您没有传递值,则认为检查 null。您传递的值可以是字符串(它将成为 连接检查)或字符串数组。

Blockly.Blocks['custom_block'] = {
  init: function() {
    this.setOutput(true); // null check
    this.setNextStatement(true, 'a connection check entry');
    this.setPreviousStatement(true, ['four', 'connection', 'check', 'entries']);
  }
}

对于输入,您可以在完成以下操作后将检查传递给 setCheck 方法 它定义了输入。如果未调用 setCheck 方法,则检查 已考虑null。您传递的值可以是字符串,也可以是字符串数组。

Blockly.Blocks['custom_block'] = {
  init: function() {
    this.appendValueInput('NAME')
        .setCheck('a connection check entry');
    this.appendStatementInput('NAME')
        .setCheck(['four', 'connection', 'check', 'entries']);
  }
}

内置检查字符串

内置块进行连接检查,值为 'Array''Boolean''Colour''Number''String'。如果您希望屏蔽规则 与内置块进行互操作,您可以使用这些值 兼容。

值示例

在为输入和输出定义连接检查时, 应将检查视为代表类型。

输入源检查应包含所有“类型”它们接受,然后输出检查 应精确包含“返回”的内容。

接受单一类型

在最基本的情况下,您需要创建一个“接受”代码块,或“退货” 一种类型,则需要在连接的连接检查中包含该类型。

接受单一类型的值块

接受多种类型

创建一个“接受”代码块,因此您需要将所有 输入的连接检查中接受的类型。

接受多种类型的值块

按照惯例,如果输出有时可在多种情况下被接受 (例如,如果您允许有时将数字用作字符串),输出应该为 限制性更高,输入更宽松。此惯例 确保输出内容不会在不受支持的地方连接。

接受任意类型

创建一个“接受”代码块,任何类型,都需要设置输入的 与 null 进行连接检查。

接受任何类型的值块

返回子类型

创建一个“返回”的子类型,因此您需要同时添加 以及输出连接检查中的超类型。

返回其类型及其超类型的值块

对于子类型,可以在输出检查中包含多个检查, 因为代码块始终“返回”两种类型。

返回参数化类型

创建一个“返回”的参数化类型,则需要同时添加 输出的 连接检查。

根据您希望屏蔽语言的严格程度,您可能还需要 包含类型的方差

返回其参数化类型和未参数化的值块
类型

与子类型一样,输出检查中可以有多个检查 在此示例中,因为该代码块始终“返回”两种类型。

堆栈或语句示例

开发者可以通过几种常见方式定义上一个和下一个的检查 连接。通常您将其视为限制代码块的排序方式。

后续连接应包括哪些块应遵循当前连接,以及 先前的连接包括当前块的“是”。

确保数据块井然有序

要创建一组按指定顺序相互关联的区块,您需要加入 哪些块应在下一次连接检查中跟随当前块,以及 当前块的“是”是什么请参阅之前的连接检查结果。

具有强制顺序的语句块

允许大量中间方块

要创建一组允许大量中间砌块的有序砌块,您需要 至少包含中间块的上一个连接签入中的条目 进行下一次连接检查这样,该代码块便可 更多本身。

允许使用大量中间块的语句块

不允许中间块

要创建一组有序的组成要素,其中中间要素是可选的,您需 包含中间块之前连接的至少一个条目 最后一个块的上一个连接检查在第一个块的下一个块中 连接检查。这样,第一个代码块后面可以跟一个中间部分 或最后一个代码块。

不允许使用中间块的语句块

“或”堆栈

创建只能后跟一个组或一组其他屏蔽的屏蔽 您需要做两件事:

  1. 您需要添加至少 1 个来自上述两个组的条目 在第一个块的下一次连接检查中进行的连接检查。

  2. 您需要定义群组的进行后续连接检查以仅包含值 包含在之前的连接检查中(因此,只能 )。

语句块可以后跟一种类型的块中的多个,或者
是另一项的倍数,但不是两者

限制

这个系统非常强大,可以满足许多应用场景, 限制。

限制更广泛的上下文

该系统本身不支持限制“更全面的上下文”在 即允许连接的连接。例如,您不能将 break 代码块只能存在于 loop 代码块内。连接 检查系统只考虑立即连接的两个连接。

可以使用事件系统来监听 阻止移动事件,并检查该代码块的位置是否有误。

Blockly.Blocks['custom_block'] = {
  init: function() { }

  onchange: function(e) {
    if (this.workspace.isDragging()) return;
    if (e.type !== Blockly.Events.BlockMove) return;
    if (!this.getSurroundLoop()) this.outputConnection.disconnect();
  }

  loopTypes: new Set(); // Your valid *block types* (not connection checks).

  getSurroundLoop: function () {
    let block = this.getSurroundParent();
    do {
      if (loopTypes.has(block.type)) return block;
      block = block.getSurroundParent();
    } while (block);
    return null;
  },
}

泛型类型

该系统本身不支持定义泛型类型。例如: 您无法创建“Identity”“返回”无论其输入是什么。

您可以在一定程度上支持此操作,方法是主动更改 来匹配其输入。您可以使用事件系统执行下列操作 监听移动事件

Blockly.Blocks['custom_block'] = {
  init: function() { }

  onchange: function(e) {
    if (e.type !== Blockly.Events.BlockMove) return;
    this.setOutput(
        true, this.getInputTargetBlock()?.outputConnection.getCheck());
  }
}

但是,如果已连接的代码块也通用,则此方法将无法正常运行。 对于这种情况,没有合适的变通方案。

连接检查工具

如果此系统不适合您的用例,您还可以更改 来比较连接检查 自定义连接检查工具

例如,如果您想创建一个更高级的系统来处理一些 限制,那么您可以创建自定义 连接检查工具。