Jump to content

Оператор безопасной навигации

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

Он используется, чтобы избежать последовательных явных проверок и присвоений значений NULL и заменить их цепочкой методов/свойств. В языках программирования, где оператор навигации (например, «.») приводит к ошибке, если применяется к пустому объекту, оператор безопасной навигации останавливает вычисление цепочки методов/полей и возвращает значение null в качестве значения выражения цепочки. Впервые он был использован Groovy 1.0 в 2007 году. [1] и в настоящее время поддерживается на таких языках, как С# , [2] Быстрый , [3] TypeScript , [4] Руби , [5] Котлин , [6] Ржавчина [7] и другие. В настоящее время для этого оператора не существует единого соглашения об именах, но оператор безопасной навигации является наиболее широко используемым термином.

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

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

Примеры операторов безопасной навигации: [8]

a[x]?.aMethod().aField // Evaluates to null if a[x] == null
a[x].aMethod()?.aField // returns null if a[x].aMethod() evaluates to null
String profileUrl = user.getProfileUrl()?.toExternalForm();
return [SELECT Name FROM Account WHERE Id = :accId]?.Name;

В C# 6.0 и выше есть ?., оператор доступа к члену с нулевым условием (который в Microsoft также называется оператором Элвиса , и его не следует путать с общим использованием термина «оператор Элвиса» , эквивалентом которого в C# является ??, нулевой оператор объединения ) и ?[], оператор доступа к условному элементу с нулевым значением , который выполняет нулевой безопасный вызов метода доступа индексатора get . Если тип результата доступа к элементу является типом значения , типом результата условного доступа к этому элементу с нулевым значением является версия этого типа значения, допускающая значение NULL . [9]

В следующем примере извлекается имя автора первой статьи в массиве статей (при условии, что каждая статья имеет Author члена и что каждый автор имеет Name член), и в результате null если массив null, если его первый элемент null, если Author участник этой статьи null, или если Name член этого автора null. Обратите внимание, что IndexOutOfRangeException по-прежнему генерируется, если массив не нулевой, но пустой (т. е. имеет нулевую длину).

var name = articles?[0]?.Author?.Name;

Для вызова лямбды требуется callback?.Invoke(), поскольку нет условного вызова с нулевым значением ( callback?() не допускается).

var result = callback?.Invoke(args);

В Clojure нет настоящих операторов в том смысле, в каком они используются в других языках, но поскольку он совместим с Java и при этом должен выполнять навигацию по объектам, some->[10] макрос можно использовать для безопасной навигации.

(some-> article .author .name)

Кофескрипт

[ редактировать ]

Экзистенциальный оператор: [11]

zip = lottery.drawWinner?().address?.zipcode

Кристалл

[ редактировать ]

Кристалл поддерживает try безопасный метод навигации [12]

name = article.try &.author.try &.name

Оператор условного доступа к членам: [13]

var name = article?.author?.name

Оператор нулевого безопасного вызова: [14]

var name = article?.author?.name

Оператор вызова с нулевой безопасностью не требуется для атрибутов класса, объявленных как свойства Gosu:

class Foo {
    var _bar: String as Bar
}

var foo: Foo = null

// the below will evaluate to null and not return a NullPointerException
var bar = foo.Bar

классный

[ редактировать ]

Оператор безопасной навигации и оператор безопасного индекса: [1] [15]

def name = article?.authors?[0].name

Добавленный в ECMAScript 2020 необязательный оператор цепочки позволяет упростить доступ к значениям через подключенные объекты, когда возможно, что ссылка или функция могут быть неопределенными или иметь значение null . [16]

const name = article?.authors?.[0]?.name
const result = callback?.()

Он сокращает всю цепочку вызовов в правой части: в следующем примере к bar не осуществляется «доступ».

null?.foo.bar

Оператор безопасного звонка: [6]

val name = article?.author?.name

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

NSString *name = article.author[0].name;

В Perl 5 такого оператора нет, но было принято предложение о его включении со следующим синтаксисом: [17]

my $name = $article?->author?->name;

В PHP 8 был принят нулевой безопасный оператор: [18]

$name = $article?->author?->name;

Раку (Перл 6)

[ редактировать ]

Безопасный вызов метода: [19]

my $name = $article.?author.?name;

Руби поддерживает &. оператор безопасной навигации (также известный как одинокий оператор ), начиная с версии 2.3.0: [5]

name = article&.author&.name

Ржавчина

[ редактировать ]

Rust предоставляет ? оператор [7] это может показаться оператором безопасной навигации. Однако ключевое отличие состоит в том, что когда ? встречает None значение, оно не оценивается как None. Вместо этого он ведет себя как return оператор, вызывающий немедленный возврат включающей функции или замыкания None.

The Option методы map() и and_then() может использоваться для безопасной навигации, но этот параметр более многословен, чем оператор безопасной навигации:

fn print_author(article: Option<Article>) {
    println!(
        "Author: {}",
        article.and_then(|y| y.author)
            .map(|z| z.name)
            .unwrap_or("Unknown".to_owned())
    );
}

Реализация с использованием ? ничего не напечатает (даже «Автор:»), если article является None или article.unwrap().author является None. Как только ? видит None, функция возвращает значение.

fn try_print_author(article: Option<Article>) -> Option<()>{
    println!("Author: {}", article?.author?.name);
    Some(())
}

Безопасный оператор в Scala предоставляется библиотекой Dsl.scala. [20] [21]

val name = article.?.author.?.name : @ ?

The @ ? аннотация может использоваться для обозначения значения, допускающего значение NULL.

case class Tree(left: Tree @ ? = null, right: Tree @ ? = null, value: String @ ? = null)

val root: Tree @ ? = Tree(
  left = Tree(
    left = Tree(value = "left-left"),
    right = Tree(value = "left-right")
  ),
  right = Tree(value = "right")
)

Нормальный . в Scala не является нулевым при выполнении метода на null ценить.

a[NullPointerException] should be thrownBy {
root.right.left.right.value // root.right.left is null!
}

Исключения можно избежать, используя ? вместо этого оператор для значения, допускающего значение NULL:

root.?.right.?.left.?.value should be(null)

Все выражение null если один из ? выполняется на null ценить.

Граница null безопасный оператор ? — ближайшее заключающее выражение, тип которого помечен как @ ?.

("Hello " + ("world " + root.?.right.?.left.?.value)) should be("Hello world null")
("Hello " + (("world " + root.?.right.?.left.?.value.?): @ ?)) should be("Hello null")
(("Hello " + ("world " + root.?.right.?.left.?.value.?)): @ ?) should be(null)

Дополнительный оператор цепочки, [3] оператор индекса и вызовите:

let name = article?.authors?[0].name
let result = protocolVar?.optionalRequirement?()

Машинопись

[ редактировать ]

Дополнительный оператор цепочки был включен в версию Typescript 3.7: [4]

let x = foo?.bar?.[0]?.baz();

Визуальный Бейсик .NET

[ редактировать ]

Visual Basic 14 и выше имеют ?. ( оператор доступа к членам с нулевым условием ) и ?() ( оператор условного индекса с нулевым значением ), аналогичный C#. Они ведут себя так же, как эквивалентные операторы в C#. [22]

Следующий оператор ведет себя идентично приведенному выше примеру C#.

Dim name = articles?(0)?.Author?.Name

См. также

[ редактировать ]
  1. ^ Jump up to: а б «Поддержка необязательного оператора пути (?.)» . Гитхаб . Проверено 4 января 2021 г.
  2. ^ «Операторы с нулевым условием (C# и Visual Basic)» . Проверено 28 января 2016 г.
  3. ^ Jump up to: а б «Необязательная цепочка» . Проверено 28 января 2016 г.
  4. ^ Jump up to: а б «Машинопись 3.7» . Проверено 6 ноября 2019 г.
  5. ^ Jump up to: а б «Выпущен Ruby 2.3.0» . Проверено 28 января 2016 г.
  6. ^ Jump up to: а б «Нулевая безопасность» . Проверено 28 января 2016 г.
  7. ^ Jump up to: а б «Оператор вопросительного знака, ?» . Проверено 4 октября 2021 г.
  8. ^ «Примечания к выпуску Salesforce Winter 21» . Сейлфорс . Проверено 13 октября 2020 г.
  9. ^ «Операторы доступа к членам (ссылка на C#)» . Документы Майкрософт . Майкрософт . Проверено 29 августа 2019 г.
  10. ^ «Руководство по потоковым макросам» . Проверено 7 июня 2019 г.
  11. ^ «Экзистенциальный оператор» . Проверено 15 июня 2017 г.
  12. ^ «Crystal API: Object#try» .
  13. ^ «Другие операторы» . Экскурсия по языку дартс . Проверено 8 января 2020 г.
  14. ^ «Язык программирования Госу» . Проверено 18 декабря 2018 г.
  15. ^ «8.5. Безопасный индексный оператор» . Проверено 25 сентября 2020 г.
  16. ^ «Необязательная цепочка» .
  17. ^ «PPC 21 — Необязательное связывание» . Гитхаб .
  18. ^ «PHP: rfc:nullsafe_operator» . wiki.php.net . Проверено 01 октября 2020 г.
  19. ^ «Операторы Раку» . Проверено 16 сентября 2022 г.
  20. ^ Платформа для создания встроенных предметно-ориентированных языков в Scala: ThoughtWorksInc/Dsl.scala , ThoughtWorks Inc., 03 июня 2019 г. , получено 3 июня 2019 г.
  21. ^ «NullSafe: оператор нулевой безопасности ? со вкусом Kotlin/Groovy теперь в Scala» . Пользователи Скалы . 12 сентября 2018 г. Проверено 3 июня 2019 г.
  22. ^ «?. и ?() операторы с нулевым условием (Visual Basic)» . Документы Майкрософт . Майкрософт . Проверено 29 августа 2019 г.
[ редактировать ]
  • PEP 505 , обсуждающая возможность безопасных операторов навигации для Python
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 8b2e1b7e81688f007821692d56679785__1708890720
URL1:https://arc.ask3.ru/arc/aa/8b/85/8b2e1b7e81688f007821692d56679785.html
Заголовок, (Title) документа по адресу, URL1:
Safe navigation operator - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)