Нет, нет «чистого» способа сделать это.
Тип array
- это примитивный тип . Объекты, реализующие интерфейс ArrayAccess
, основаны на классах, также известных как композитный тип . Нет никакого типа-намека, который охватывает оба.
Поскольку вы используете ArrayAccess
в качестве массива, вы можете просто его бросить. Например:
$config = new Config;
$lol = new I_Use_A_Config( (array) $config);
Если это не опция (вы хотите использовать объект Config
как есть), просто удалите подсказку типа и проверьте, что это либо массив, либо ArrayAccess
. Я знаю, что вы хотели этого избежать, но это не очень важно. Это всего лишь несколько строк и, когда все сказано и сделано, несущественны.
В этом случае не имеет особого смысла использовать оператор switch, поскольку вы рассматриваете несколько сравнений строк.
Вместо этого вы можете выполнить поиск в таблице на основе таблицы, отсортированной в алфавитном порядке:
const char* STR_TABLE[] = // must be sorted in alphabetic order
{
"exit",
"history",
"parse",
...
};
const size_t STR_TABLE_SIZE = sizeof(STR_TABLE) / sizeof(STR_TABLE[0]);
Затем можно выполнить поиск в таблице правильной строки. Наивной реализацией является цикл for:
for(size_t i=0; i<STR_TABLE_SIZE; i++)
{
if(strcmp(STR_TABLE[i], user_input)==0)
{
// found, do something
break;
}
}
Это лучший вариант, когда количество строк в таблице ограничено. Для больших таблиц вы должны использовать бинарный поиск. Примерно так:
int strcmp_wrapper (const void* obj1, const void* obj2)
{
return strcmp(obj1, *(const char**)obj2);
}
const char** result = bsearch(user_input,
STR_TABLE,
STR_TABLE_SIZE,
sizeof(const char*),
strcmp_wrapper);
if(result != NULL)
{
printf("User picked option %s at index %d.", *result, (int)(result - STR_TABLE));
}
switch
-условие будет работать только с целочисленными значениями. Существует switch
-частичное использование:
switch(a)
{
case '1': doSomething(); break; // if you forget break operator, than second
case also will invoke and so one
case '2': doSomethingElse(); break;
default: doSomethingElse2();
}
Вы можете использовать switch
-статмент, если вам нужно работать с целочисленными значениями / константами из определенного диапазона. [ 117]
в настоящее время ваш код выглядит так:
blockquote>if(command_line[0] == '!') { <recall> } else if(strcmp(command_line, "exit") == 0) { <exit> } else if(strcmp(command_line, "history") == 0) { <historic> } else if(strncmp(command_line, "parse", 5) == 0) { <parse> } else { <other> }
использование переключателя даст что-то вроде этого:
switch (command_line[0]) { case '!': <recall> break; case 'e': if(strcmp(command_line + 1, "xit") == 0) { <exit> } else { <other> } break case 'h': if(strcmp(command_line + 1, "istory") == 0) { <historic> } else { <other> } break case 'p': if(strncmp(command_line + 1, "arse", 4) == 0) { <parse> break; } // no fallthrough default: { <other> } }
Это менее читабельно, облегчает введение ошибки, если она должна быть изменена, и не оказывает благотворного влияния на скорость, если это то, что вы ожидали
Для меня не делайте этого ... но спросите себя о strcmp , но strncmp в одном случае