0

各ノードの横にチェックボックスが付いたツリー コントロールがあり、ノードでチェック済み、チェックなし、中間のチェック済みの状態を許可します。ノードをクリックすると、親と子が更新されます。私が見つけたコードはビットシフトを使用しており、正確に何が起こっているのかを理解しようとしています.

誰かが次のコードを説明できますか? または、さらに良いことに、このコードを書き直して、理解しやすくしますか?

// click event handler
private function eventMessageTree_itemCheckHandler(event:TreeEvent):void {
  var node:ITreeNode = ITreeNode(event.item);
  var checkState:uint = TreecheckboxItemRenderer(event.itemRenderer).checkBox.checkState;
  updateParents(node, checkState);
  updateChilds(node, checkState);
}

private function updateChilds(item:ITreeNode, value:uint):void {
  var middle:Boolean = (value & 2 << 1) == (2 << 1);
  var selected:Boolean = (value & 1 << 1) == (1 << 1);

  if (item.children.length > 0 && !middle) {
    for each (var childNode:ITreeNode in item.children)     {
      childNode.checked = value == (1 << 1 | 2 << 1) ? "2" : value == (1 << 1) ? "1" : "0";
      updateChilds(childNode, value);
    }
  }
}

private function updateParents(item:ITreeNode, value:uint): void {
  var checkValue:String = (value == (1 << 1 | 2 << 1) ? "2" : value == (1 << 1) ? "1" : "0");
  var parentNode:ITreeNode = item.parent;
  if (parentNode) {
    for each (var childNode:ITreeNode in parentNode.children) {
      if (childNode.checked != checkValue) {
        checkValue = "2";
      }
    }
    parentNode.checked = checkValue;
    updateParents(parentNode, value);
  }    
}
4

2 に答える 2

1

基本的には、次のような表現です。

var middle:Boolean = (value & 2 << 1) == (2 << 1);

直感に反します。通常、定数 1 を左にシフトしてビットをテストします。これにより、シフトされるビット数がビットのインデックスと同じになり、LSB (右端) ビットがビット番号 0 としてカウントされます。

また、結果は常に 0 または非ゼロになるため、== 比較で結果をテストしても意味がありません。そのため、言語でそれが必要な場合は、少なくともより単純なものをテストできます。

デフォルトでゼロ以外の整数を「真」と解釈する C および C++ では、比較はまったく不要であり、煩雑さ、繰り返しを導入し、バグのリスクを高めるだけです。

私はこれを次のように書きます:

var middle:Boolean = (value & (1 << 2)) != 0;

追加の括弧は、物事がどのようにグループ化されているかを明確にするのに役立ちます. 「2 << 1」が「1 << 2」に書き換えられたことに注意してください。これは単なる「スイッチ」ではありません。同じビット値 (この場合は 4) を取得するには、適切なシフトを計算する必要があります。

もちろん、ビットテストをサブルーチンに入れて呼び出し、コードを読みやすくすることもできます。

于 2009-03-19T10:26:34.387 に答える