Пропавшие без вести возвращения сводят меня с ума

# #function #go #slice

Вопрос:

Я пытаюсь научиться Идти, и все идет очень хорошо, за исключением операторов возврата функций, которые я не могу понять за всю свою жизнь. В упражнении в книге предлагается построить функцию, которая делит int пополам и возвращает разделенное на две части int, а если четное или нечетное (разделенное пополам), то с помощью bool. С этим проблем нет, вот соответствующий код.

 func checker(input int) (int, bool){
    if (((input /2) % 2) == 0) {
        return input / 2, true
    } else {
        return input / 2, false
    }
}
 

Но при попытке преобразовать это, чтобы принять кусочек, я клянусь, что не могу понять, где отсутствуют возвраты. Вот снова соответствующий код для этого:

 func checker(args ...int) (int, bool){
    for _, v := range args {
        if (((v /2) % 2) == 0) {
            return v / 2, true
        } else {
            return v / 2, false
        }
    }
}

func main () {
    xs := []int{3,45,6,32,43,76,42,4,77,8}
    fmt.Println(checker(xs...))
}
 

Я думаю, что теперь я понимаю некоторые проблемы кода, который я представил, спасибо вам за ваши ответы.

Комментарии:

1. Версия среза не имеет смысла по нескольким причинам, и возврат отсутствует, если, например, переданный срез пуст.

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

3. Если передача 0 аргументов недопустима, panic паника в конце функции, указывающая на недопустимый вызов, не потребует возврата

4. @Vvyibaba Меня это нисколько не беспокоило, наоборот, именно об этом и идет речь в этом вопросе. Я просто хотел, чтобы вы знали, что кроме отсутствующего возврата в конце есть дополнительные проблемы с вашей функцией. Это также было указано в ответе icza. Цикл всегда возвращается на первой итерации и поэтому проверяет только первый элемент среза.

Ответ №1:

Нет никакой гарантии checker() , что будет получено больше нуля аргументов, и в этом случае тело цикла будет выполнено ноль раз, поэтому никакие return операторы не будут достигнуты.

Таким образом, компилятор вправе жаловаться на отсутствие возврата, поскольку это условие решается во время выполнения.

Например , если вы передадите 0 аргументы: checker() , это допустимо и вызовет проблемы, если a return не будет востребован.

Поэтому просто добавьте return оператор с разумными возвращаемыми значениями, часто нулевыми значениями типов результатов:

 func checker(args ...int) (int, bool){
    for _, v := range args {
        if (((v /2) % 2) == 0) {
            return v / 2, true
        } else {
            return v / 2, false
        }
    }
    return 0, false
}
 

Также обратите внимание, что этот цикл проверяет только первый переданный аргумент и возвращает, вероятно, не то, что вы хотите.

Комментарии:

1. Спасибо вам за ответ. Я попытался выполнить проверку по этому поводу, но не знал, как ничего не возвращать, если это так, и выдать ошибку. проверка прошла примерно так: «проверка функций(args …int) (int, bool){ если (len(args) == 0){ // код для побега } еще { //предыдущий цикл for } }« Разве этого недостаточно?

2. func checker(args ...int) (int, bool){ if (len(args) == 0){ // the code to escape } else { //the previous for loop } } (надеюсь, он обнаружит это как код)

3. Вам не нужно его обнаруживать. Просто добавьте правильное return утверждение с разумными значениями, например, с нулевыми значениями.

4. Реализация исправления, предложенного всеми о добавлении идиотского возврата, привлекла мое внимание к неработоспособности, еще одна вещь, о которой стоит беспокоиться, учитывая, что код взят (и немного адаптирован) для другой части указанной книги. Я посмотрю, почему это так, но это уже другой вопрос сам по себе.

5. Я полагаю, что он возвращает только первое, потому что в этом случае возврат «завершает» функцию и больше не выполняется.

Ответ №2:

Вы возвращаетесь только в области цикла For. Вернитесь после цикла for. Если ваши аргументы пусты, то ваш цикл не выполняется и возвраты не достигнуты. Поэтому вам нужно добавить возврат после цикла for.

Я предлагаю рассматривать это как сценарий ошибки или что-то в этом роде. Ниже я упомянул простое решение для этого.

 func checker(args ...int) (int, bool){
    for _, v := range args {
        if ((v /2) % 2 == 0) {
            return v / 2, true
        } else {
            return v / 2, false
        }
    }
    return 0, false
}
 

Комментарии:

1. Если я правильно понимаю в вашем примере, мы будем рассматривать это как идиотский возврат и фильтровать его в main (), но когда не ожидается никакого идиотского ответа и существует аналогичный цикл, как это будет обработано? Пример: переменная функция, которая делит пополам любое значение с плавающей точкой и возвращает результат.

2. вам нужно вернуть ошибку, например «длина отправленного массива должна быть больше нуля».