Note: information on this page refers to Ceylon 1.2, not to the current release.
Conditions and condition lists
Ceylon allows one or more conditions, which together form a condition list,
in the if
, while
, and assert
statements and in if
comprehension clauses.
Note: This page is not describing the is
,
exists
, and nonempty
operators, which are considered a part of the expression grammar.
Usage
A condition list may occur in an if
, while
, or
assert
statements, or in an if
clause of a
comprehension.
Description
A condition list is satisfied if and only if every condition in the list is
satisfied. The difference between a comma-separated condition list and a single
Boolean
condition constructed using the &&
operator
is that a condition list may narrow the type of a reference, or introduce a new
reference.
Integer m(Object x) {
if (is Integer x, x < 10) {
// x is of type Integer here
return x + 1;
}
return 0;
}
Note: In the following discussion we will use if
in the code examples.
Keep in mind that condition lists may also occur in a while
or assert
statement.
Boolean conditions
A boolean condition is an expression of type Boolean
. It is satisfied
if the expression evaluates to true
.
is
conditions
A condition of form is Y x
is satisfied if the reference x
evaluates
to an instance of the type Y
. Within the associated block, x
will have
the type X&Y
, where X
is the previous type of x
.
In other words, if (is Y x)
similar to Java's if (x instanceof Y)
,
immediately followed by a typecast, (Y) x
.
Integer plusOneIfInteger(Object x) {
if (is Integer x) {
// x is of type Integer here
return = x+1;
}
return 0;
}
It's even possible to introduce a new local reference in the condition, in which case it is the new local reference which has the narrowed type:
Integer plusOneIfInteger(Object x) {
if (is Integer i=x) {
// x still of type Object here
// but i is an Integer
return i+1;
}
return 0;
}
For a variable
reference or getter you are required to use this form.
On a platform that supports concurrency this protects you from another
thread changing the value while the block protected by the if
is being
executed (and potentially violating the guarantees of the type system).
It is acceptable to specify a generic type in an is
condition, for
example, if (is List<Integer> list)
to distinguish a List<Integer>
from a List<String>
.
Note: Do not confuse the is
condition of form is Type t
with
an is
operator of form t is Type
.
exists
conditions
A condition of form exists x
means is Object x
, and is satisfied
if the reference x
refers to a non-null
value. Within the associated
block, x
will have the non-optional type X&Object
, where X
is the
previous type of x
.
In other words, if (exists x)
is similar to Java's if (x != null)
.
Integer plusOneIfExists(Integer? x) {
if (exists x) {
// x is of type Integer here
return x+1;
}
return 0;
}
It's possible to introduce a new local reference in the condition, in which case it is the new local reference that has the narrowed type:
Integer plusOneIfExists(Integer? x) {
if (exists i=x) {
// x still of type Integer? here
return i+1;
}
return 0;
}
Note: Do not confuse the exists
condition of form exists t
with an exists
operator of form t exists
.
nonempty
conditions
A condition of form nonempty xs
means is [X+] xs
, where X
is the
element type of the sequence reference x
, and is satisfied if the x
refers to a nonempty sequence. Within the associated block, x
will
have the nonempty type [X+]
.
Integer firstPlusOne(Integer[] xs) {
if (nonempty xs) {
// xs of type [Integer+] here
return xs.first+1;
}
return 0;
}
It's possible to introduce a new local reference in the condition, in which case it is the new local reference which has the narrowed type:
Integer firstPlusOne(Integer[] xs) {
if (nonempty ys=xs) {
// xs still of type Integer[] here
return ys.first+1;
}
return 0;
}
Note: Do not confuse the nonempty
condition of form nonempty xs
with a nonempty
operator of form xs nonempty
.
See also
-
if
statement, -
while
statement, assert
statement- comprehensions
- Control structure conditions in the Ceylon language spec