Здесь кое-что происходит ...
Объявление [...]
создает фактический массив вместо среза, поэтому удаление косвенности удаляется. То, что объявляется здесь, представляет собой массив типов interface{}
... так что вы можете задаться вопросом, почему странная нотация карты?
Переменные StateXXX
- это просто константы, объявленные выше, поэтому они являются ints ... так что объявление действительно имеет форму index: value
.
Ниже представлен менее запутанный пример того, что использование массива ints:
var i = [...]int{4: 2, 2: 7}
Это будет выделение массива содержащий:
[0, 0, 7, 0, 2]
... обратите внимание, что индекс 2 имеет 7, индекс 4 имеет 2. Не является общепринятым способом объявления массива, но он действителен. Go.
вернемся к первоначальному объявлению, просто возьмите пример, который я привел выше, а вместо int сделаем массив типа interface{}
:
var i = [...]interface{}{4: 2, 2: 7}
И вы получите аналогичный массив, но с nil
вместо нулей.
Подойдя ближе к исходному коду, константы StateXXX
- это просто ints, только не литералы, как в моем примере.
Итак, в чем смысл всего этого? Почему все обфускации?
Это взлом производительности. Функция c.curState.Store()
принимает аргумент типа interface{}
. Если вы должны передать ему int, скомпилированный код должен был бы перепутаться с преобразованием типа для каждого вызова. Более ясная (хотя, очевидно, непрактичная) иллюстрация этого может быть:
var val interface{}
for i := 0; i < 1000000; i++ {
// the types are different, compiler has to fumble int vs. interface{}
val = i
// do something with val
}
Каждый раз, когда вы делаете val = i
, должно произойти преобразование между int
и interface{}
. Выделенный вами код избегает этого, создавая статическую таблицу поиска, где все значения уже интерфейса типа.
Поэтому это:
c.curState.Store(connStateInterface[state])
более эффективен, чем это:
c.curState.Store(state)
Так как state
, в этом случае, необходимо пройти преобразование int -> interface{}
. В оптимизированном коде state
представляет собой просто индекс, который ищет значение в массиве, результат которого дает вам interface{}
... поэтому избежать преобразования типа int -> interface{}
.
Я не знаком с этим кодом, но я бы предположил, что он находится на критическом пути, и наносекунды или любые сбережения сбережения, вероятно, имеют значение.
CASE
возвращает значение первого (сверху вниз) выражения THEN
, которое имеет выражение WHEN
, которое оценивается как true (и ELSE
, если ничего не найдено). Поскольку ваше первое WHEN
также верно в случаях, когда второе верно, выбирается первое, а не второе. Всегда ставьте более узкий WHEN
перед менее узкими в CASE
.
CASE
WHEN (type_txt = 'ACCOUNT' AND status = 'ACTIVE' AND code = 483 AND open_date < CURRENT_DATE) THEN 0
WHEN (type_txt = 'ACCOUNT' AND status = 'ACTIVE' THEN 1
ELSE 0
END
Поместите дополнительное условие в тот же случай:
sum(
CASE
WHEN
type_txt = 'ACCOUNT'::text
AND status = 'ACTIVE'
AND NOT (code = 483 AND open_date < CURRENT_DATE)
THEN 1
ELSE 0
END) AS accounts_actv