В объектно-ориентированном программировании , то безопасный оператор навигации (также известный как дополнительный оператор цепного , оператор безопасного вызова , нуль-условный оператор ) представляет собой бинарный оператор , который возвращает нулевое значение , если первый аргумент пустой; в противном случае он выполняет операцию разыменования, как указано вторым аргументом (обычно доступ к члену объекта, индекс массива или вызов лямбда-выражения).
Он используется, чтобы избежать последовательных явных проверок и присваиваний null и заменить их цепочкой методов / свойств. В языках программирования, где оператор навигации (например, «.») Приводит к ошибке при применении к нулевому объекту, оператор безопасной навигации останавливает оценку цепочки методов / полей и возвращает значение NULL в качестве значения выражения цепочки. В настоящее время он поддерживается в таких языках, как Apex , [1] Apache Groovy , [2] Swift , [3] Ruby , [4] C # , [5] Kotlin , [6] CoffeeScript , Scala , [7] Dart [8].и другие. В настоящее время нет единого соглашения об именах для этого оператора, но оператор безопасной навигации является наиболее широко используемым термином.
Основное преимущество использования этого оператора заключается в том, что он позволяет избежать пирамиды гибели . Вместо того, чтобы писать несколько вложенных if
s, программисты могут просто использовать обычную цепочку, но добавлять символы вопросительного знака перед точками (или другими символами, используемыми для цепочки).
В то время как в безопасности оператор навигации и нулевой оператор коалесцирующих оба нулевых-операторы знают , что они оперативно различны.
Примеры
Вершина
Примеры оператора безопасной навигации: [9]
а [ х ]? . aMethod (). aField // Возвращает значение null, если a [x] == null a [ x ] . aMethod () ? . aField // возвращает null, если a [x] .aMethod () оценивается как null String profileUrl = user . getProfileUrl () ? . toExternalForm (); вернуть [ ВЫБРАТЬ имя ИЗ учетной записи ГДЕ Id = : accId ]? . Имя ;
Groovy
Оператор безопасной навигации и оператор безопасного индекса: [2] [10]
def name = article ?. авторы ? [ 0 ]. название
Цель-C
Нормальный синтаксис навигации может использоваться в большинстве случаев без учета NULL, поскольку базовые сообщения при отправке в NULL отбрасываются без каких-либо негативных последствий.
NSString * name = article . автор [ 0 ]. имя ;
Быстрый
Необязательный оператор цепочки, оператор индексации [3] и вызов:
пусть имя = статья ?. авторы ? [ 0 ]. имя let result = protocolVar ?. optionalRequirement ? ()
Рубин
Ruby поддерживает &.
оператор безопасной навигации (также известный как оператор одиночества ), начиная с версии 2.3.0: [4]
name = article &. автор &. название
C #
C # 6.0 и выше , имеет ?.
, то нуль-условный оператор доступ члена (который также называется оператором Элвиса от Microsoft , и не следует путать с общим использованием термина оператора Элвиса , чей эквивалент в C # является ??
, то нулем коалесценции оператора ) и ?[]
, то нуль-оператор условного доступа элемента , который выполняет нулевой безопасный вызов индексатора ПОЛУЧИТЬ аксессор . Если тип результата доступа к члену является типом значения , тип результата условного доступа с нулевым значением этого члена является версией этого типа значения, допускающей значение NULL . [11]
В следующем примере извлекается имя автора первой статьи в массиве статей (при условии, что каждая статья имеет Author
член и что каждый автор имеет Name
член), и приводит к тому, есть null
ли массив null
, если его первый элемент null
, если Author
членом этой статьи null
, или если Name
член этого автора null
. Обратите внимание, что по- IndexOutOfRangeException
прежнему генерируется , если массив не равен нулю, но пуст (т.е. имеет нулевую длину).
var name = article ? [ 0 ] ?. Автор ? Имя ;
Вызов лямбда-выражения требует callback?.Invoke()
, так как нет нулевого условного вызова ( callback?()
не разрешено).
var result = callback ?. Вызов ( аргументы );
Visual Basic .NET
Visual Basic 14 и более поздних версий имеют ?.
( оператор условного доступа к члену с нулевым значением ) и ?()
( оператор условного индекса с нулевым значением ), как и в C #. Они ведут себя так же, как эквивалентные операторы в C #. [12]
Следующий оператор ведет себя идентично приведенному выше примеру C #.
Тусклое имя = статьи ? ( 0 ) ? . Автор ? . Имя
Госу
Оператор нулевого безопасного вызова: [13]
var name = article ?. автор ? название
Нулевой безопасный оператор вызова не требуется для атрибутов класса, объявленных как Gosu Properties:
class Foo { var _bar : String as Bar }var foo : Foo = ноль// приведенное ниже значение будет равно null и не вернет исключение NullPointerException var bar = foo . Бар
Котлин
Оператор безопасного вызова: [6]
val name = article ?. автор ? название
Раку (Perl 6)
Вызов безопасного метода: [14]
мое $ name = $ article .? автор .? имя ;
PHP
В PHP 8 был принят нулевой безопасный оператор: [15]
$ name = $ article ? -> автор ? -> name ;
Python
Оператор безопасной навигации не поддерживается в Python. Предлагалось для включения со следующим синтаксисом: [16]
# Предлагаемый синтаксис, еще не являющийся частью языка: name = article ? . автор ? . название
JavaScript
Добавленный в ECMAScript 2020 необязательный оператор цепочки предоставляет способ упростить доступ к значениям через подключенные объекты, когда возможно, что ссылка или функция могут быть неопределенными или нулевыми . [17]
const name = article ? . авторы ? . [ 0 ] ? . имя const результат = обратный вызов ? . ()
CoffeeScript
Экзистенциальный оператор: [18]
zip = лотерея . ничьяПобедитель ? (). адрес ? . индекс
Машинопись
Необязательный оператор цепочки был включен в версию Typescript 3.7: [19]
пусть x = foo ? . бар ? . baz ();
Кристалл
Crystal поддерживает метод try
безопасной навигации [20]
имя = статья . попробуйте &. автор . попробуйте &. название
Ржавчина
Ржавчина поддерживает ?
и try!{}
операторы для структур , реализующих Try
черту. [21]
// Предпочтительный метод быстрого возврата ошибок fn write_to_file_question () -> Result < (), MyError > { let mut file = File :: create ( "my_best_friends.txt" ) ? ; файл . write_all ( b "Это список моих лучших друзей." ) ? ; Хорошо (())}// Предыдущий метод быстрого возврата ошибок fn write_to_file_using_try () -> Result < (), MyError > { let mut file = r # попробовать ! ( File :: create ( "my_best_friends.txt" )); г # попробуй ! ( file . write_all ( b «Это список моих лучших друзей.» )); Хорошо (())}
Scala
Нулевой безопасный оператор в Scala предоставляется библиотекой Dsl.scala. [22]
val name = article .?. автор .?. имя : @ ?
@ ?
Аннотации можно использовать для обозначения обнуляемого значения.
case class Tree ( слева : Tree @ ? = null , справа : Tree @ ? = null , значение : String @ ? = null )val root : Tree @ ? = Дерево ( слева = Дерево ( слева = Дерево ( значение = "слева-слева" ), справа = Дерево ( значение = "слева-справа" ) ), справа = Дерево ( значение = "справа" ) )
Нормаль .
в Scala не является нулевой безопасностью при выполнении метода над null
значением.
[ NullPointerException ] должен быть thrownBy { корень . правильно . слева . правильно . value // root.right.left равно нулю! }
Исключения можно избежать, используя ?
вместо этого оператор для значения, допускающего значение NULL:
корень .?. правильно ?. осталось .?. значение должно быть ( null )
Все выражение - это null
если одно из значений ?
выполняется null
.
Граница null
безопасного оператора ?
- это ближайшее включающее выражение, тип которого аннотируется как @ ?
.
( "Hello" + ( "world" + root .?. Right .?. Left .?. Value )) должно быть ( "Hello world null" ) ( "Hello" + (( "world" + root .?. Right .?. left .?. value .?) : @ ? )) должен быть ( "Hello null" ) (( "Hello" + ( "world" + root .?. right .?. left .?. value .?. )) : @ ? ) должно быть ( null )
Clojure
Clojure не имеет настоящих операторов в том смысле, в котором его используют другие языки, но поскольку он взаимодействует с Java и должен выполнять навигацию по объектам, когда это происходит, макрос some->
[23] может использоваться для выполнения безопасной навигации.
( Some-> статья .author .name )
Дротик
Оператор условного доступа к члену: [8]
var name = article ? . автор ? . название
Смотрите также
Рекомендации
- ^ «Оператор безопасной навигации | Руководство разработчика Apex | Разработчики Salesforce» . developer.salesforce.com . Проверено 13 октября 2020 .
- ^ а б «Необязательная цепочка» . Проверено 28 января 2016 . CS1 maint: обескураженный параметр ( ссылка )
- ^ а б «Выпущен Ruby 2.3.0» . Проверено 28 января 2016 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «Нулевые-условные операторы (C # и Visual Basic)» . Проверено 28 января 2016 . CS1 maint: обескураженный параметр ( ссылка )
- ^ а б «Нулевая безопасность» . Проверено 28 января 2016 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «NullSafe: Null-safe со вкусом Kotlin / Groovy? Оператор теперь в Scala» . Пользователи Scala . 2018-09-12 . Проверено 3 июня 2019 .
- ^ а б «Другие операторы» . Экскурсия по языку Дарт . Проверено 8 января 2020 .
- ^ «Примечания к выпуску Salesforce Winter 21» . Salesforce . Проверено 13 октября 2020 .
- ^ «8.5. Безопасный оператор индекса» . Проверено 25 сентября 2020 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «Операторы доступа к членам (справочник по C #)» . Документы Microsoft . Microsoft . Проверено 29 августа 2019 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «?. и? () условные операторы NULL (Visual Basic)» . Документы Microsoft . Microsoft . Проверено 29 августа 2019 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «Язык программирования Госу» . Проверено 18 декабря 2018 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «Операторы Раку» . Проверено 28 июня 2016 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «PHP: rfc: nullsafe_operator» . wiki.php.net . Проверено 1 октября 2020 .
- ^ «PEP 505 - Операторы без информации» . Проверено 27 августа 2018 . CS1 maint: обескураженный параметр ( ссылка )
- ^ https://tc39.es/proposal-optional-chaining/
- ^ «Экзистенциальный оператор» . Проверено 15 июня 2017 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «Машинопись 3.7» . Проверено 6 ноября 2019 . CS1 maint: обескураженный параметр ( ссылка )
- ^ «Crystal API: объект # попробовать» .
- ^ "Trait std :: ops :: Try" . Проверено 26 февраля 2019 . CS1 maint: обескураженный параметр ( ссылка )
- ^ Платформа для создания встроенных доменно-специфичных языков в Scala: ThoughtWorksInc / Dsl.scala , ThoughtWorks Inc., 03.06.2019 , получено 03.06.2019.
- ^ «Руководство по макросам потоков» . Проверено 7 июня 2019 . CS1 maint: обескураженный параметр ( ссылка )
Внешние ссылки
- PEP 505 , обсуждая возможность операторов безопасной навигации для Python