Оператор безопасной навигации
Эта статья нуждается в дополнительных цитатах для проверки . ( январь 2016 г. ) |
В объектно-ориентированном программировании оператор безопасной навигации (также известный как необязательный оператор цепочки , оператор безопасного вызова , оператор с условием нуля , оператор распространения нуля ) — это бинарный оператор, который возвращает значение NULL , если его первый аргумент равен нулю; в противном случае он выполняет операцию разыменования, указанную вторым аргументом (обычно доступ к члену объекта, индекс массива или вызов лямбда-выражения).
Он используется, чтобы избежать последовательных явных проверок и присвоений значений NULL и заменить их цепочкой методов/свойств. В языках программирования, где оператор навигации (например, «.») приводит к ошибке, если применяется к пустому объекту, оператор безопасной навигации останавливает вычисление цепочки методов/полей и возвращает значение null в качестве значения выражения цепочки. Впервые он был использован Groovy 1.0 в 2007 году. [1] и в настоящее время поддерживается на таких языках, как С# , [2] Быстрый , [3] TypeScript , [4] Руби , [5] Котлин , [6] Ржавчина [7] и другие. В настоящее время для этого оператора не существует единого соглашения об именах, но оператор безопасной навигации является наиболее широко используемым термином.
Основное преимущество использования этого оператора заключается в том, что он позволяет избежать пирамиды гибели . Вместо написания нескольких вложенных if
s, программисты могут просто использовать обычную цепочку, но добавлять символы вопросительного знака перед точками (или другими символами, используемыми для цепочки).
Хотя оператор безопасной навигации и оператор объединения нулей оба являются операторами, осознающими нуль , в функциональном отношении они различны.
Примеры
[ редактировать ]Апекс
[ редактировать ]Примеры операторов безопасной навигации: [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
JavaScript
[ редактировать ]Добавленный в ECMAScript 2020 необязательный оператор цепочки позволяет упростить доступ к значениям через подключенные объекты, когда возможно, что ссылка или функция могут быть неопределенными или иметь значение null . [16]
const name = article?.authors?.[0]?.name
const result = callback?.()
Он сокращает всю цепочку вызовов в правой части: в следующем примере к bar не осуществляется «доступ».
null?.foo.bar
Котлин
[ редактировать ]Оператор безопасного звонка: [6]
val name = article?.author?.name
Цель-C
[ редактировать ]Обычный синтаксис навигации можно использовать в большинстве случаев без учета NULL, поскольку базовые сообщения, отправленные в NULL, отбрасываются без каких-либо побочных эффектов.
NSString *name = article.author[0].name;
Перл 5
[ редактировать ]В Perl 5 такого оператора нет, но было принято предложение о его включении со следующим синтаксисом: [17]
my $name = $article?->author?->name;
PHP
[ редактировать ]В 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
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ «Операторы с нулевым условием (C# и Visual Basic)» . Проверено 28 января 2016 г.
- ^ Jump up to: а б «Необязательная цепочка» . Проверено 28 января 2016 г.
- ^ Jump up to: а б «Машинопись 3.7» . Проверено 6 ноября 2019 г.
- ^ Jump up to: а б «Выпущен Ruby 2.3.0» . Проверено 28 января 2016 г.
- ^ Jump up to: а б «Нулевая безопасность» . Проверено 28 января 2016 г.
- ^ Jump up to: а б «Оператор вопросительного знака, ?» . Проверено 4 октября 2021 г.
- ^ «Примечания к выпуску Salesforce Winter 21» . Сейлфорс . Проверено 13 октября 2020 г.
- ^ «Операторы доступа к членам (ссылка на C#)» . Документы Майкрософт . Майкрософт . Проверено 29 августа 2019 г.
- ^ «Руководство по потоковым макросам» . Проверено 7 июня 2019 г.
- ^ «Экзистенциальный оператор» . Проверено 15 июня 2017 г.
- ^ «Crystal API: Object#try» .
- ^ «Другие операторы» . Экскурсия по языку дартс . Проверено 8 января 2020 г.
- ^ «Язык программирования Госу» . Проверено 18 декабря 2018 г.
- ^ «8.5. Безопасный индексный оператор» . Проверено 25 сентября 2020 г.
- ^ «Необязательная цепочка» .
- ^ «PPC 21 — Необязательное связывание» . Гитхаб .
- ^ «PHP: rfc:nullsafe_operator» . wiki.php.net . Проверено 01 октября 2020 г.
- ^ «Операторы Раку» . Проверено 16 сентября 2022 г.
- ^ Платформа для создания встроенных предметно-ориентированных языков в Scala: ThoughtWorksInc/Dsl.scala , ThoughtWorks Inc., 03 июня 2019 г. , получено 3 июня 2019 г.
- ^ «NullSafe: оператор нулевой безопасности ? со вкусом Kotlin/Groovy теперь в Scala» . Пользователи Скалы . 12 сентября 2018 г. Проверено 3 июня 2019 г.
- ^ «?. и ?() операторы с нулевым условием (Visual Basic)» . Документы Майкрософт . Майкрософт . Проверено 29 августа 2019 г.
Внешние ссылки
[ редактировать ]- PEP 505 , обсуждающая возможность безопасных операторов навигации для Python