Я не javascript, но я нашел здесь для поиска этой проблемы. Для тех, у кого это есть и найти здесь, я надеюсь, что это поможет некоторым. Итак, если у вас есть список переключателей:
Я могу найти, какой из них выбран с этим селектором:
$('.list input[type="radio"]:checked:first').val();
Даже если нет элемента выбрано, я до сих пор не получаю неопределенную ошибку. Таким образом, вам не нужно писать дополнительную инструкцию if, прежде чем принимать значение элемента.
Вот очень простой пример jsfiddle .
Похоже, вы создаете какую-то мини-тестовую среду с использованием препроцессора c.
1112 Есть предостережение для тел; для препроцессора C фигурные скобки и квадратные скобки являются просто токенами. Выражения в скобках распознаются (то есть, скобки совпадают), а запятые распознаются как разделители. Так, например, этот вызов макроса:
test(dosomething, { int a = add(1, 1); assert(a == 2); })
... имеет два аргумента, несмотря на наличие двух запятых (потому что вторая запятая «обнята» в наборе в скобках), но это немного вводит в заблуждение. Этот вызов:
test(dosomething, { enum { red, green, blue }; assert(red+1==green); })
... имеет четыре аргумента: 1: dosomething
, 2: { enum { red
, 3: green
и 4: blue }; assert(red+1==green); }
. Если вы собираетесь это сделать, вы, вероятно, захотите охватить такие случаи, как это ... есть базовые стратегии: (а) обнять тело в скобках (вы можете развернуть его в расширении) или (б) использовать макросы с переменным числом аргументов.
Их нужно повторить. blockquote>Похоже на работу для x-macros (ниже я буду использовать параметризованный макрокоманду x-macros). [ 1115]
Но более того, я хотел бы передать обратный вызов для асинхронных функций, чтобы сказать, что они завершены, например: blockquote>... вы не можете добавить аргумент в середине, но фигурные скобки не должны быть частью этого (они все равно не помогают, так как препроцессор их игнорирует). Так что для вышеизложенного мы, вероятно, хотим выбрать вариант объятия. В результате ваши вызовы выглядят так:
test(dosomething, (int a=add(1,1); assert(a==2);), done)
Однако, поскольку мы вырываем фигурные скобки, мы можем поместить их в произвольные места в нашем расширении и делать произвольные вещи между ними. Так как я предполагаю, что вы хотите, чтобы происходила та же асинхронная вещь, мы могли бы просто поместить эту вещь в расширение, которое генерирует определение, а не аргумент.
Вот примерно то, на что это было бы похоже, используя параметризованную макро-версию x-макроса и применяя асинхронное расширение (используя семафоры, чтобы продемонстрировать, насколько это может быть произвольно):
#define APPLY_TEST_MACROS(macro) \ macro(test_add, (int a=add(1,1); assert(a==2); )) \ macro(test_sub, (int a=sub(5,2); assert(a==3); )) \ macro(test_mul, (int a=mul(3,4); assert(a==12); )) #define UNWRAP(...) __VA_ARGS__ #define MAKE_ASYNC_SEM(NAME_, BODY_) \ void NAME_() { \ sem_wait(&test_sem_ctl); print(#NAME_); sem_post(&test_sem_ctl); \ UNWRAP BODY_ \ sem_wait(&test_sem_ctl); \ if (0==--tests_remaining) sem_post(&test_sem_done); \ sem_post(&test_sem_ctl); \ } #define COUNT_TESTS(NAME_, BODY_) +1 sem_t test_sem_ctl; sem_t test_sem_done; void init_semaphores() { sem_init(&test_sem_ctl, 0, 1); sem_init(&test_sem_done, 0, 0); } // iterate over tests to count them unsigned int tests_remaining = APPLY_TEST_MACROS(COUNT_TESTS); // define the tests APPLY_TEST_MACROS(MAKE_ASYNC_SEM)
.. и так далее (я останавливаюсь здесь, потому что идея состоит в том, чтобы передать идею, а не кодировать ее для вас). Макет x-macro позволяет вам выполнять итерации в препроцессоре, так что вы можете сделать что-то вроде порождения потока за тест; вы могли бы также просто использовать этот же подход для построения массива тестовых функций, если, скажем, вы хотите передать свои тесты в пул потоков.