переключение оператора без перерыва - PullRequest
8 голосов
/ 11 ноября 2010

Как получается опция case в операторе switch, которая не содержит перерыв, автоматически пересылается в следующий case без проверки?

try {
    switch($param) {
        case "created":
            if(!($value instanceof \DateTime))
                throw new \Exception("\DateTime expected, ".gettype($value)." given for self::$param");
        case "Creator":
            if(!($value instanceof \Base\User)) {
                throw new \Exception(get_class($value)." given. \Base\User expected for self::\$Creator");                  
            }
        default:
            $this->$param = $value;
            break;
    }
} catch(Exception $e) {
    echo $e->getMessage();
}

Если параметр «создан», он выполнит проверку в созданном случае, что хорошо. Когда проверка прошла успешно, я хочу, чтобы код продолжал использовать параметр по умолчанию, поэтому разрыв не ставится ;. Но вместо этого он продолжает "Создатель", пока $ param! = "Создатель"!

Я знаю, как решить эту проблему (просто добавьте код по умолчанию в моем случае «создан»), но я не люблю повторять этот код слишком часто. Мой актуальный вопрос: почему это продолжается с делом «Создатель», в то время как дело не «Создатель».

Ответы [ 5 ]

19 голосов
/ 11 ноября 2010

Fallthrough был преднамеренной особенностью дизайна для разрешения кода, подобного:

switch ($command) {
  case "exit":
  case "quit":
    quit();
    break;
  case "reset":
    stop();
  case "start":
    start();
    break;
}

Он разработан таким образом, что выполнение сокращается от случая к случаю.

default - такой же случай, как и любой другой, за исключением того, что прыжок происходит, если не было запущено ни одного другого случая.Это ни в коем случае не инструкция «сделай это после запуска фактического выбранного случая».В вашем примере вы могли бы рассмотреть:

  switch($param) {
    case "created":
        if(!($value instanceof \DateTime))
            throw new \Exception("\DateTime expected, ".gettype($value)." given for self::$param");
        break;
    case "Creator":
        if(!($value instanceof \Base\User)) {
            throw new \Exception(get_class($value)." given. \Base\User expected for self::\$Creator");                  
        }
        break;
}

$this->$param = $value;

Практическое правило здесь, если это не зависит от переключателя, переместите его из переключателя.

1 голос
/ 11 ноября 2010

Я действительно не вижу, что вы хотите.

  1. Если вы хотите запускать вещи по умолчанию во всех случаях, просто поставьте их после переключателя.
  2. Если вы хотитечтобы запустить материал по умолчанию только в «созданном» случае и в случае по умолчанию, поменяйте местами разделы «созданный» и «создатель» и поставьте разрыв после первого.
  3. Если вы хотите этот кодзапускаться только если Creator или созданные совпадения, затем избавиться от оператора switch и использовать if / else OR, использовать флаг и следующий оператор if.

Все инструменты есть.

1 голос
/ 11 ноября 2010

Возможно, это вас просветит:

Вопрос переключателя Table Jump Case

1 голос
/ 11 ноября 2010

Потому что это так в C .

0 голосов
/ 11 ноября 2010

Чтобы ответить на ваш «актуальный вопрос»: Почему это продолжается с делом «Создатель», когда дело не является «Создателем».

Поскольку у вас нет break,Без этого он продолжит дела ниже.Единственное решение, которое я могу придумать, - это добавить код по умолчанию в дела и добавить break.

. Кроме того, вам не нужно break для дела по умолчанию, так как это последний случай в коммутатореблок.

...