Должен ли метод поиска возвращать 'null' или генерировать исключение, когда он не может выдать возвращаемое значение? [закрыто]

У меня есть метод, который должен вернуть объект, если он найден.

Если он не найден, я должен:

  1. вернуть ноль
  2. выдать исключение
  3. прочее
485
задан 14.11.2017, 03:39

30 ответов

Если Вы всегда ожидаете находить, что значение тогда выдает исключение, если это отсутствует. Исключение означало бы, что была проблема.

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

более важный: Что Вы делаете другие места в коде? Непротиворечивость важна.

465
ответ дан 04.10.2019, 12:45
  • 1
    @Ken: +1, было бы хорошо упомянуть, что, если Вы действительно выдаете исключение, но может обнаружить его априорно (как HasItem (...)), тогда пользователь должен обеспечить, сказал, Имеет* или Содержит метод. – user7116 07.10.2008, 12:29
  • 2
    Если Вы выдаете исключения в образцовых методах, это вынуждает разработчика разработать блоки попытки/выгоды из объема вызова, который гарантирует, что стандартные программы, называя те образцовые методы обрабатываются правильно от того объема. Иначе разработчик мог сделать то, что они хотят. Считайте его интерфейсом для вызова образцовых методов, если Вы будете. Если данные не там, it' s, вероятно, необходимо будет сделать некоторое обходное решение так или иначе. – axiom82 31.05.2014, 08:50

Возвратите пустой указатель, исключения точно что: что-то, что Ваш код делает, который не ожидается.

1
ответ дан 04.10.2019, 12:45

Или возвратите Опцию

, опция является в основном контейнерным классом, который вынуждает клиент обработать случаи стенда. У Scala есть это понятие, ищите, это - API.

Тогда Вы имеете методы как T getOrElse (T valueIfNull) на этом объекте thet или возвращаете найденный объект или альтернативу клиент specifieces.

2
ответ дан 04.10.2019, 12:45

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

1
ответ дан 04.10.2019, 12:45
  • 1
    Я надеюсь называть методы на объекте, например, str.match(/\d/) – tihom 14.04.2020, 22:32

Я соглашаюсь с тем, что, кажется, согласие здесь (возвратите пустой указатель, если "не найденный" нормальный возможный исход, или выдайте исключение, если семантика ситуации требует, чтобы объект всегда был найден).

существует, однако, третья возможность, которая могла бы иметь смысл в зависимости от Вашей конкретной ситуации. Ваш метод мог возвратить какой-то объект по умолчанию в "не найденном" условии, позволив коду вызова быть гарантированным, что это будет всегда получать доступный объект без потребности в пустой ловле проверки или исключения.

1
ответ дан 04.10.2019, 12:45

Пока это, как предполагается, возвращается , ссылка к объекту, возвращая ПУСТОЙ УКАЗАТЕЛЬ должна быть хорошей.

Однако, если это возвращает целую кровавую вещь (как в C++, если Вы делаете: 'возвратите вздор'; вместо 'возврата &blah'; (или 'вздор' является указателем), тогда Вы не можете возвратить ПУСТОЙ УКАЗАТЕЛЬ, потому что это не имеет типа 'объект'. В этом случае выдача исключения или возврат пустого объекта, который не имеет флага успеха, устанавливают, то, как я приблизился бы к проблеме.

1
ответ дан 04.10.2019, 12:45
  • 1
    Я верю попытке использования направляющих, потому что все - метод. пользователь [' name'] возвратит средство доступа ' name' но won' t возвращают метод ' name' на пользовательском экземпляре. – zungaphobia 14.04.2020, 22:33

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

  • Объект найден; эхо-сигнал
  • незнакомый Объект; выдайте исключение

Иначе, возвратите пустой указатель.

0
ответ дан 04.10.2019, 12:45

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

1
ответ дан 04.10.2019, 12:45

Обычно это должно возвратить пустой указатель. Код, называя метод должен решить, выдать ли исключение или делать попытку чего-то еще.

2
ответ дан 04.10.2019, 12:45
  • 1
    Привет Tony, я действительно консультировался с той страницей также, и у меня было то же понимание. Но я хотел спросить сообщество, так как некоторые сайты (как тот, который я загнал как ссылка) рассматривают единственное строковое значение как допустимый json ответ. Наблюдение ответов здесь просто подтвердить это, не имеет смысла. – Sylvain Demers 12.11.2012, 15:08

Если для клиентского кода важно знать различие между найденным и не найденное, и это, как предполагается, стандартное поведение, то лучше возвращать пустой указатель. Клиентский код может тогда решить, что сделать.

2
ответ дан 04.10.2019, 12:45
  • 1
    Я попробовал тот сайт, и я соглашаюсь с Вами, это кажется вводящим в заблуждение. Обычно я использую jsonlint.com , который не принимает строку как допустимый JSON: " Ошибка анализа на строке 1: " ciao" ^, Ожидающий ' {' ' [' ". сообщение об ошибке является четким: это ожидает Объект или Массив. – Tony Rad 12.11.2012, 17:56

Согласовывайтесь с API, который Вы используете.

13
ответ дан 04.10.2019, 12:45
  • 1
    имело бы какой-либо смысл комбинировать горизонтальные и вертикальные ядра путем создания одного действительной частью и одной мнимая часть, и затем можно ли найти величину путем получения брюшного пресса (результат)? – endolith 10.04.2014, 17:41

Вот пара большего количества предложений.

При возврате набора, постарайтесь не возвращать пустой указатель, возвратите пустой набор, который делает перечисление легче иметь дело с без пустой проверки сначала.

Несколько использования API.NET шаблон thrownOnError параметра, который дает вызывающей стороне выбор как, является ли это действительно исключительной ситуацией или не, если объект не найден. Ввести. GetType является примером этого. Другой общий шаблон с BCL является шаблоном TryGet, куда булевская переменная возвращается, и значение передается через выходной параметр.

Вы могли также рассмотреть шаблон Несуществующего объекта при некоторых обстоятельствах, которые могут или быть значением по умолчанию или версией без поведения. Ключ, избегают пустых проверок всюду по кодовой базе. Посмотрите здесь для получения дополнительной информации http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx

4
ответ дан 04.10.2019, 12:45

Исключения связаны для Разработки согласно Контракту.

интерфейс объекты являются на самом деле контрактом между двумя объектами, вызывающая сторона должна выполнить контракт, или иначе получатель может просто перестать работать за исключением. Существует два возможных контракта

1) весь вход, метод действителен, в этом случае необходимо возвратить пустой указатель, когда объект не найден.

2) только некоторый вход допустим, т.е. то, что приводит к найденному объекту. В этом случае НЕОБХОДИМО предложить второй метод, который позволяет вызывающей стороне определять, будет ли его вход корректен. Например

is_present(key)
find(key) throws Exception

, ЕСЛИ и ТОЛЬКО ЕСЛИ Вы предоставляете оба метода 2-го контракта, Вам разрешают выдать исключение, ничто, найден!

5
ответ дан 04.10.2019, 12:45
  • 1
    Привет я плохо знаком с этим, я создал основной класс и получил эту ошибку, можно ли сказать мне как запись основной класс для него? Sobel = новый Sobel (); MarvinImage imgIn = MarvinImageIO.loadImage (" unnamed2.jpg"); MarvinImage imgOut = MarvinImageIO.loadImage (" тест jpg"); a.process (imgIn, imgOut); Исключение в потоке " main" java.lang. NullPointerException в Sobel.process(Sobel.java:41) –  22.04.2014, 15:26

Зависит от того, что это означает, что объект не найден.

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

, Если это - ошибка, затем выдайте исключение, вызывающие стороны должны решить, что сделать с состоянием ошибки недостающего объекта.

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

4
ответ дан 04.10.2019, 12:45

Я предпочитаю просто возвращать пустой указатель и полагаться на вызывающую сторону для обработки его соответственно. (Из-за отсутствия лучшего слова) исключение - то, если я 'абсолютно уверен', что этот метод возвратит объект. В этом случае отказ является исключительным, должен и должен бросить.

4
ответ дан 04.10.2019, 12:45

это зависит, если Ваш язык и код продвигают: LBYL (взгляд перед прыганием) или EAFP (легче спросить прощение, чем разрешение)

LBYL заявляет, что необходимо проверить на значения (так возвратите пустой указатель)
EAFP заявляет, чтобы просто попробовать операцию и видеть, перестало ли это работать (выдайте исключение)

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

<час>

EAFP по сравнению с LBYL в Python:
http://mail.python.org/pipermail/python-list/2003-May/205182.html ( веб-Архив )

11
ответ дан 04.10.2019, 12:45

Просто спросите себя: "действительно ли это - исключительный случай, которым не найден объект"? Если это, как ожидают, произойдет в нормальном ходе Вашей программы, Вы, вероятно, не должны повышать исключение (так как это не исключительное поведение).

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

- Alan.

11
ответ дан 04.10.2019, 12:45

Используйте шаблон несуществующего объекта или выдайте исключение.

18
ответ дан 04.10.2019, 12:45
  • 1
    Это - реальный ответ. Возврат пустого указателя является ужасной привычкой к ленивым программистам. – jeremyjjbrown 24.05.2013, 09:01
  • 2
    Я can' t верят этому ответу hasn' t проголосовавший вершине все же. Это - реальный ответ, и или подход очень легок и сохраняет много чрезмерного увеличения размера кода или NPEs. – Bane 07.09.2013, 03:16
  • 3

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

В C++, я могу думать о 3 различных разновидностях об установке метода, который находит объект.

пустой указатель Возврата Опции A

Object *findObject(Key &key);

, когда объект не может быть найден. Хороший и простой. Я пошел бы с этим. Альтернативные подходы ниже для людей, которые не ненавидят-params.

Передача Опции B

void findObject(Key &key, Object &found);

в ссылке на переменную, которая будет получать объект. Метод, выданный исключение, когда объект не может быть найден. Это соглашение, вероятно, более подходит, если оно, как действительно ожидают, для объекта не не будет найдено - следовательно Вы выдаете исключение, чтобы показать, что это - неожиданный случай.

Опция C

bool findObject(Key &key, Object &found);

метод возвращает false, когда объект не может быть найден. Преимущество этого по опции A состоит в том, что можно проверить на ошибочный случай на одном ясном шаге:

if (!findObject(myKey, myObj)) { ...
3
ответ дан 04.10.2019, 12:45

Я просто хотел резюмировать опции, упомянутые прежде, добавляя некоторые новые:

  1. пустой указатель возврата
  2. выдает Исключение
  3. , используют шаблон несуществующего объекта
  4. , предоставляют булев параметр Вам метод, таким образом, вызывающая сторона может, выбрал, если он хочет, чтобы Вы выдали исключение
  5. , обеспечивают дополнительный параметр, таким образом, вызывающая сторона может установить значение, которое он возвращает, если никакое значение не найдено

, Или Вы могли бы объединить эти опции:

Обеспечивают несколько перегруженных версий Вашего метода get, таким образом, вызывающая сторона может решить который способ пойти. В большинстве случаев только первый имеет реализацию алгоритма поиска, и другие просто переносят первый:

Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);

, Даже если Вы принимаете решение обеспечить только одну реализацию, Вы могли бы хотеть использовать соглашение о присвоении имен как этот для разъяснения контракта, и помогает, что Вы должны Вы когда-либо решать добавить другие реализации также.

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

25
ответ дан 04.10.2019, 12:45

В некоторых функциях я добавляю параметр:

..., bool verify = true)

Истинный бросок средств, ложные средства возвращают некоторое ошибочное возвращаемое значение. Таким образом, кто бы ни использует эту функцию, имеет обе опции. Значение по умолчанию должно быть верным, в пользу тех, кто забывает об обработке ошибок.

3
ответ дан 04.10.2019, 12:45

Как правило, если метод должен всегда возвращать объект, то пойдите за исключением. Если Вы ожидаете случайный пустой указатель и хотите обработать его определенным способом, пойдите с пустым указателем.

Независимо от того, что Вы делаете, я высоко отговариваю от третьей опции: Возврат строки, которая говорит "WTF".

66
ответ дан 04.10.2019, 12:45
  • 1
    Плюс тот, потому что в добрые старые времена я сделал это больше, чем пару раз как быстрый грязный " temporal" не зафиксируйте... хорошую идею. Особенно, если его попытка быть рассмотренным, если Вы - студент. – rciafardone 14.03.2014, 04:48
  • 2
    Большое спасибо! Дальнейший вопрос состоит в том, как обернуть данные в данные формы? решение в это сообщение кажется, не работает на методы Ресурса (может работать на $http.put). спасибо – Edward 17.02.2020, 10:59

Если пустой указатель никогда не указывает, что ошибка тогда просто возвращает пустой указатель.

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

, Если пустой указатель является иногда исключением тогда, кодируют две стандартных программы. Одна стандартная программа выдает исключение, и другой булева тестовая задача, которая возвращает объект в выходном параметре, и стандартная программа возвращает false, если объект не был найден.

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

Поэтому, когда пустой указатель является ошибкой, Вы просто пишете

object o = FindObject();

, Когда пустой указатель не является ошибкой, можно кодировать что-то как

if (TryFindObject(out object o)
  // Do something with o
else
  // o was not found
50
ответ дан 04.10.2019, 12:45
  • 1
    Это было бы более полезным предложением, если бы C# обеспечил реальные кортежи, таким образом, мы могли избегать использования параметр. Однако, это - предпочтительный шаблон, таким образом, +1. – Erik Forbes 07.10.2008, 09:07
  • 2
    По-моему, подход попытки является лучшим. Вы don' t должны искать тогда, что происходит, если объект не может быть возвращен. С методом Попытки Вы сразу знаете, что сделать. – OregonGhost 07.10.2008, 10:52

Только выдайте исключение, если это - действительно ошибка. Если это - ожидаемое поведение для объекта не существовать, возвратите пустой указатель.

Иначе это - вопрос предпочтения.

96
ответ дан 04.10.2019, 12:45
  • 1
    прокомментируйте = Comment.save ($scope.newComment, (ответ)-> console.log (" Комментарий отправлен "))... работает также. – mikeborgh 17.02.2020, 10:59

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

Иначе я просто возвратил бы пустой указатель, если это действительно не исключительный случай, когда объект не найден.

0
ответ дан 04.10.2019, 12:45

В коде слоя данных я несколько раз использую следующий код, позволяя вызывающей стороне решить, означает ли "объект, не найденный", что ошибка произошла.


DataType GetObject(DBConnection conn, string id, bool throwOnNotFound) {
    DataType retval = ... // find object in database
    if (retval != null || ! throwOnNotFound) {
        return retval;
    } else {
        throw new NoRowsFoundException("DataType object with id {id} not found in database");
    }
}

DataType GetObject(DBConnection conn, string id) {
    return GetObject(conn, id, true);
} 
0
ответ дан 04.10.2019, 12:45

Не находя это - исключительное событие (т.е. это должно там произойти при нормальных обстоятельствах), то бросьте. Иначе возвратитесь, "не найденное" значение (может быть пустым, но не имеет к), или даже имейте возврат метода булевская переменная для найденного/незнакомого и параметр для фактического объекта.

0
ответ дан 04.10.2019, 12:45

Это зависит от природы метода и как это будет использоваться. Если это - нормальное поведение, которым объект не может быть найден, затем возвратить пустой указатель. Если это - нормальное поведение, которым всегда находится объект, выдайте исключение.

Как показывает опыт, используйте исключения только для того, когда что-то исключительное произойдет. Не пишите код таким способом, которым бросок исключения и ловля являются частью своего нормального функционирования.

0
ответ дан 04.10.2019, 12:45

Это зависит от Вашего метода. Если Вы, метод, как предполагается, всегда возвращает доступный объект и ни один не найден, выдавание исключения является способом пойти. Если метод просто ment для возврата объекта, который мог бы или не мог бы быть там (как, возможно, изображение на контактном лице), Вы не должны повышать ошибку.

Вы могли бы также хотеть представить метод, возвращая булевскую переменную, истинную/ложную, если этот метод на самом деле возвратит объект, таким образом, Вы не должны будете или a) проверять на пустой указатель или b) ловить исключение

0
ответ дан 04.10.2019, 12:45

Это не содержащий объект может произойти во время нормального функционирования и должно иметься дело с ПУСТЫМ УКАЗАТЕЛЕМ возврата вызывающей стороны.

, Если не содержащий объект указывает, ошибка кодом вызова или внутренним состоянием тогда делает утверждение.

, Если не содержащий объект указывает на нечастое событие. (Как кто-то удалил объект из хранилища, в то время как Вы проверяли объект одновременно.) Тогда выдают исключение.

0
ответ дан 04.10.2019, 12:45

Теги

Похожие вопросы