Safe navigation operator
In object-oriented programming, the safe navigation operator (also known as optional chaining operator, safe call operator, null-conditional operator, null-propagation operator) is a binary operator that returns null if its first argument is null; otherwise it performs a dereferencing operation as specified by the second argument (typically an object member access, array index, or lambda invocation). It is used to avoid sequential explicit null checks and assignments and replace them with method/property chaining. In programming languages where the navigation operator (e.g. ".") leads to an error if applied to a null object, the safe navigation operator stops the evaluation of a method/field chain and returns null as the value of the chain expression. It was first used by Groovy 1.0 in 2007[1] and is currently supported in languages such as C#,[2] Swift,[3] TypeScript,[4] Ruby,[5] Kotlin,[6] Rust,[7] JavaScript,[8] and others. There is currently no common naming convention for this operator, but safe navigation operator is the most widely used term. The main advantage of using this operator is that it avoids the pyramid of doom. Instead of writing multiple nested While the safe navigation operator and null coalescing operator are both null-aware operators, they are operationally different. ExamplesApexSafe navigation operator examples in Apex:[9] 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#C# 6.0 and above have The following example retrieves the name of the author of the first article in an array of articles (provided that each article has an var name = articles?[0]?.Author?.Name;
Calling a lambda requires var result = callback?.Invoke(args);
ClojureClojure doesn't have true operators in the sense other languages uses it, but as it interoperable with Java, and has to perform object navigation when it does, the (some-> article .author .name)
CoffeeScriptExistential operator:[12] zip = lottery.drawWinner?().address?.zipcode
CrystalCrystal supports the name = article.try &.author.try &.name
DartConditional member access operator:[14] var name = article?.author?.name
GosuNull safe invocation operator:[15] var name = article?.author?.name
The null-safe invocation operator is not needed for class attributes declared as Gosu Properties: 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
GroovySafe navigation operator and safe index operator:[1][16] def name = article?.authors?[0].name
JavaScriptAdded in ECMAScript 2020, the optional chaining operator provides a way to simplify accessing values through connected objects when it's possible that a reference or function may be undefined or null.[17] Major desktop browsers have supported this since 2020, and most mobile browsers added support by 2024.[18] const name = article?.authors?.[0]?.name
const result = callback?.()
It short-circuits the whole chain of calls on its right-hand side: in the following example, bar is not "accessed". null?.foo.bar
KotlinSafe call operator:[6] val name = article?.author?.name
Objective-CNormal navigation syntax can be used in most cases without regarding NULLs, as the underlying messages, when sent to NULL, is discarded without any ill effects. NSString *name = article.author[0].name;
Perl 5Perl 5 does not have this kind of operator, but a proposal for inclusion was accepted with the following syntax:[19] my $name = $article?->author?->name;
PHPThe null safe operator was accepted for PHP 8:[20] $name = $article?->author?->name;
Raku (Perl 6)Safe method call:[21] my $name = $article.?author.?name;
RubyRuby supports the name = article&.author&.name
RustRust provides a The fn print_author(article: Option<Article>) {
println!(
"Author: {}",
article.and_then(|y| y.author)
.map(|z| z.name)
.unwrap_or("Unknown".to_owned())
);
}
An implementation using fn try_print_author(article: Option<Article>) -> Option<()>{
println!("Author: {}", article?.author?.name);
Some(())
}
ScalaThe null-safe operator in Scala is provided by the library Dsl.scala.[22] [23] val name = article.?.author.?.name : @ ?
The 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")
)
The normal a[NullPointerException] should be thrownBy {
root.right.left.right.value // root.right.left is null!
}
The exception can be avoided by using root.?.right.?.left.?.value should be(null)
The entire expression is The boundary of a ("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)
SwiftOptional chaining operator,[3] subscript operator, and call: let name = article?.authors?[0].name
let result = protocolVar?.optionalRequirement?()
TypeScriptOptional chaining operator was included in the Typescript 3.7 release:[4] let x = foo?.bar?.[0]?.baz();
Visual Basic .NETVisual Basic 14 and above have the The following statement behaves identically to the C# example above. Dim name = articles?(0)?.Author?.Name
See alsoReferences
External links
|
Portal di Ensiklopedia Dunia