Неправильное использование охранного заявления для замены нулевой проверки

Я делаю что-то очень простое, чтобы просто привыкнуть к Swift (исходя из objc) - я хочу вернуть нужный узел в связанный список, используя guard заявление и switch заявление. Я явно неправильно использую guard заявление, потому что мой else предложение огромно (здесь хранится мое заявление о переключении). Возможно, мне даже не нужна switch заявление, но это просто немного проясняет ситуацию.

Мой старый код выглядит следующим образом:

func getValue (atIndex index: Int) -> T {
    if count < index || index < 0 {
        print ("index is outside of possible range")
    }
    var root = self.head
    //        if var root = self.head {
    if index == 0 {
        return (self.head?.value)!
    }
    if index == count-1 {
        return (self.tail?.value)!
    }
    else {
        for _ in 0...index-1 {
            root = root!.next!
        }
    }
    return root!.value
}

Заменено на guard оператор (но получая ошибку компилятора, из-за которой тело охраны может не провалиться) - моя проблема в том, что возвращать, так как тип возвращаемой функции <T> (любой тип).

func getValue (atIndex index: Int) -> T {
    guard  (count < index || index < 0) else {
        switch true {
        case index == 0:
            if let head = self.head {
                return head.value
            }
        case index == count-1:
            if let tail = self.tail {
                return tail.value
            }
        default:
            if var currentNode = head {
                for _ in 0...index-1 {
                    currentNode = currentNode.next!
                }
                return currentNode.value
            }
        }
    }
}

Я хотел бы добавить print заявление за пределами моего guard утверждение о том, что искомый индекс находится за пределами диапазона, но мне также нужно что-то возвращать в конце функции типа T, Проблема в том, что за пределами моего guard и поменять заявление, мне нечего возвращать.

2 ответа

Решение

guard оператор используется для отлова неверного регистра, поэтому вы захотите что-то вроде:

func getValueAtIndex(index: Int) -> T {
    guard index >= 0 && index < count else {
        // Invalid case
        print("Index is outside of possible range")

        // Guard must return control or call a noreturn function.
        // A better choice than the call to fatalError might be
        // to change the function to allow for throwing an exception or returning nil.
        fatalError("Index out of bounds")
    }

    // Valid cases
}

guard Заявление предназначено для перемещения программы из ее текущей области видимости или вызова noreturn функционировать, если найдено значение nil, Вы, однако, управляете целым switch утверждение в вашем guard,

Согласно документации Apple по охране:

else пункт о guard оператор требуется, и должен либо вызвать функцию, отмеченную noreturn управление атрибутом или передачей программы вне области действия оператора защиты, используя один из следующих операторов:

  • вернуть
  • перерыв
  • Продолжить
  • бросать

Хороший пример guard возможно:

var optValue : String?

guard let optValue = optValue else {return}
Другие вопросы по тегам