建立自定義塊 - 型別檢查

weixin_34320159發表於2018-02-07

title: 建立自定義塊 - 型別檢查

Type Checks
<原文地址:https://developers.google.com/blockly/guides/create-custom-blocks/type-checks

Blockly建模動態型別語言(如JavaScript或Python)。它缺少靜態型別語言(如Java或C ++)的嚴格規則。更具體地說,任何值都可以賦給任何變數,在變數定義中沒有int,bool或float。

然而,Blockly確實有能力防止一些沒聯絡(non-sensical combinations )組合的構建。以下三個塊沒有業務相互連線:

2433593-ab2461633ade1543.png

每個Blockly的連線型別(值輸入/輸出,下一個/上一個語句)都可以用型別資訊標記,以使明顯無效的連線將拒絕連線。這給使用者即時的反饋,並避免許多簡單的錯誤。

值輸入和輸出


讓我們從一個數字塊開始。當指定輸出時,也可以設定型別字串。因為這個塊應該返回一個數字,讓我們將輸出型別設定為字串'Number':

json

{  
    "type": "math_number",  
    // ...  
    "output": "Number",
}

js

Blockly.Blocks['math_number'] = {
  init: function() {
    // ...
    this.setOutput(true, 'Number');
  }
};
2433593-d987728b5f3bb201.png

更復雜的塊是確定數字是否為偶數的數學塊。這個塊有一個期望一個數字的輸入,和一個返回一個布林的輸出。這裡是指定這樣的程式碼:

json

{
  "type": "math_number_property",
  // ...
  "args0": [
      // ...
      {
        "type": "input_value",
        "name": "NUMBER_TO_CHECK",
        "check": "Number"
      }
  ],
  "output": "Boolean"
}

js

Blockly.Blocks['math_number_property'] = {
  init: function() {
    // ...
    this.appendValueInput('NUMBER_TO_CHECK').setCheck('Number');
    this.setOutput(true, 'Boolean');
  }
};
2433593-4248d29804ffcdbd.png

當數字塊連線到此數學塊時,兩個連線的型別都為“Number”,因此連線成功。而如果一個人試圖將一個文字塊(輸出型別為'String')插入數學塊,那麼這兩種型別將不匹配,並且連線將拒絕連線。

“ength of”類似,除了它需要能夠接受文字塊或列表塊。因此,不是一個字串,它的輸入型別被設定為兩個選項的陣列:

json

{
  "type": "text_length",
  // ...
  "args0": [
      // ...
      {
        "type": "input_value",
        "name": "VALUE",
        "check": ["String", "Array"]
      }
  ],
  "output": "Number"
}

js

Blockly.Blocks['text_length'] = {
  init: function() {
    // ...
    this.appendValueInput('VALUE').setCheck(['String', 'Array']);
    this.setOutput(true, 'Number');
  }
};
2433593-6433533aeebb3742.png

塊可以想象地返回兩種或更多種型別中的一種。雖然在Blockly中沒有當前的例子,但是通過將輸出型別設定為型別陣列來支援。如果輸入中的任何單個型別與輸出中的型別匹配,則可以連線塊。

變數是可以儲存任何型別的值塊的示例。因此,它們的型別設定為null,表示萬用字元:

json

{
  "type": "variable_get",
  // ...
  "output": null
}

js

Blockly.Blocks['variable_get'] = {
  init: function() {
    // ...
    // Second parameter for type is optional, and null is the default.
    this.setOutput(true);
  }
};
2433593-50cc9da3efb2e589.png

允許將塊插入任何輸入,而不管輸入的型別。

請注意,Blockly('Number','Boolean','String','Array','Color')中使用的型別字串是完全任意的。任何字串都是可接受的,並且新的字串可以是專門的。只是確保輸出和輸入之間的一致性。

語句堆疊


以與輸入和輸出的水平連線可以型別相同的方式,垂直語句堆疊也可以具有型別資訊。大多數編碼應用程式不會使用此功能,因為任何語句通常可以遵循任何其他語句。

2433593-ef1d4b9f438bfb09.png

型別語句連線的一個罕見示例可以在Blockly開發工具的Block Factory選項卡中看到。注意,欄位塊可以不被堆疊在輸入塊應該去的地方,並且輸入塊可以不被堆疊在欄位塊應該去的地方。

有三個地方定義了型別化語句:一個塊的上一個和下一個連線,以及一個語句輸入的連線。它們定義塊的頂部和底部的堆疊槽口,它們只能連線到其槽口未設定型別或其槽口包含至少一個匹配型別的塊。

以下示例演示“Mouse”和“Rat”型別,其中可以將任一型別的塊新增到語句輸入RODENTS。然而,這個玩具例子不支援齧齒動物列表中的老鼠和鼠。

json

{
  "type": "append_mouse",
  "message0": "Mouse",
  "previousStatement": "Mouse",
  "nextStatement": "Mouse"
},
{
  "type": "rodent_list",
  "message0": "Rodents %1",
  "args0": [
      {
        "type": "input_statement",
        "name": "RODENTS",
        "check": ["Mouse", "Rat"]
      }
  ]
}

js

Blockly.Blocks['append_mouse'] = {
  init: function() {
    this.appendDummyInput().appendField('Mouse');
    this.setPreviousStatement(true, 'Mouse');
    this.setNextStatement(true, 'Mouse');
  }
};
Blockly.Blocks['rodent_list'] = {
  init: function() {
    this.appendDummyInput().appendField('Rodents');
    this.appendStatementInput('RODENTS')
        .setCheck(['Mouse', 'Rat']);
  }
};
2433593-9a6d9f5fad40cd3f.png

相關文章