оператор "ИЛИ" ТСЛ - PullRequest
       8

оператор "ИЛИ" ТСЛ

0 голосов
/ 08 ноября 2018

Это не вопрос, связанный с TCL, как я знаю ... Я пишу это в этом теге.
Можно узнать, какая переменная неверна, когда я пишу:

set l1 0
set l2 2

if {$l1 == 0 || $l2 == 1} {
    return {your variable $l1 or $l2 is not correct}
}

Во избежание этого пишу:

if {$l1 == 0} {
    return {your variable $l1 is not correct}
}

if {$l2 == 1} {
    return {your variable $l2 is not correct}
}

есть лучшее решение?

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

Это еще один способ сделать это. Лучше ли это зависит от вас:

foreach {name val} {l1 0 l2 1} {
    upvar 0 $name var
    if {$var == $val} {
        return "your variable $name is not correct"
    }
}
0 голосов
/ 09 ноября 2018

В определенных ситуациях, особенно когда у вас много переменных и вы точно знаете границы переменных (минимальное и максимальное значение переменных), вы можете использовать словарь и побитовый &.

Пример ниже будет таким, где каждая переменная может иметь 2 возможных значения (0 или 1, это пример, основанный на том, как рассчитываются разрешения на чат Discord).

set permissions {
  perm1   0x00000001
  perm2   0x00000002
  perm3   0x00000004
  perm4   0x00000008
  perm5   0x00000010
  perm6   0x00000020
  perm7   0x00000040
  perm8   0x00000080
}

set permDict [dict create {*}$permissions]

proc getPermList {perms} {
  # Ensure perms is an integer
  if {![string is integer -strict $perms]} {
    return -code error "Not an integer: $perms"
  }
  # This list will contain matched permissions
  set permList [list]
  dict for {permission value} $::permDict {
    if {$perms & $value} {
      lappend permList $permission
    }
  }
  # Return the list
  return $permList
}

В приведенном выше, каждое разрешение имеет следующие значения:

Perm     Hexadecimal   Binary      Decimal
perm1 -> 0x00000001 -> 00000001 ->   1
perm2 -> 0x00000002 -> 00000010 ->   2
perm3 -> 0x00000004 -> 00000100 ->   4
perm4 -> 0x00000008 -> 00001000 ->   8
perm5 -> 0x00000010 -> 00010000 ->  16
perm6 -> 0x00000020 -> 00100000 ->  32
perm7 -> 0x00000040 -> 01000000 ->  64
perm8 -> 0x00000080 -> 10000000 -> 128

А конкретная комбинация разрешений будет иметь сумму отдельных разрешений. Например, если у кого-то есть и perm1, и perm4, их общие разрешения будут равны 9. Обратный будет использовать процедуру, описанную выше; у нас есть значение 9, и мы хотим знать, какие разрешения у этого человека. Таким образом, мы сделаем getPermList 9 и получим в результате: perm1 perm4.

В двоичном коде 9 представляется как:

00001001

А индивидуальные разрешения perm1 и perm4 следующие:

00000001
00001000

Добавление двух (сложение чисел по вертикали) дает двоичное представление числа 9. Так что же здесь происходит?

Цикл (dict for) сравнивает каждое значение dict с разрешением, для которого мы хотим детализацию:

perm1
Binary:  00001001    Decimal:    9
       & 00000001             &  1
       = 00000001             =  1

Поскольку результат больше 0, perm1 - это одно из разрешений, которое предоставляется разрешению с общим значением 9.

perm2
Binary:  00001001    Decimal:    9
       & 00000010             &  2
       = 00000000             =  0

Поскольку результат равен 0, perm2 не является одним из разрешений, которые предоставляются разрешению с общим значением 9. Цикл продолжается, и мы обнаруживаем, что единственный раз, когда он дает ненулевой результат, это perm4 :

perm4
Binary:  00001001    Decimal:    9
       & 00001000             &  8
       = 00001000             =  8

Вы можете прочитать, как поразрядно и работает по ссылке в Википедии, которую я имею в начале, но по сути, 1 & 1 дает 1, 1 & 0, 0 & 1 и 0 & 0 все дают 0.

Если у кого-то есть все разрешения, у него будет значение разрешения 255 (1 + 2 + 4 + ... + 128), а если вы сделаете getPermList 255, вы получите все разрешения, перечисленные в словарь.

0 голосов
/ 08 ноября 2018

номер
Если вы хотите узнать, какая переменная неверна, у вас есть проверить конкретную переменную.

Вы можете уменьшить дублирование текста:

set errstr "your variable %s (value %s) is not correct"
if { $l1 == 0 } {
  return [format $errstr l1 $l1]
}
if { $l2 == 1 } {
  return [format $errstr l2 $l2]
}

Но это просто стиль кодирования, и на самом деле это не так важно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...