Description
openedon Mar 3, 2015
Update:
@kballard has a better suggestion than I did at #929 (comment) . Similar type of idea but borrows from Swift.
Original idea below.
Seems like a good idea to support &&
in if let
expressions. I'm not sure about ||
. It seems good from a consistency standpoint but I'm not sure if the the fact that the destructuring could result in different types could present a problem or not. In #525 it was a problem so I'd anticipate a problem here as well.
fn main() {
// `op_op` (option option)
let op_op = Some(Some(6));
// Leads to deep nesting which is bad.
if let Some(op) = op_op {
if let Some(i) = op {
println!("Matched {:?}, {:?}!", op, i);
}
}
// It'd be nice to support the `&&` operator. `op_op` destructures
// then `op` destructures. These would be directly equivalent.
if let Some(op) = op_op &&
Some(i) = op {
println!("Matched {:?}, {:?}!", op, i);
}
// With `else`
if let Some(op) = op_op {
if let Some(i) = op {
println!("Matched {:?}, {:?}!", op, i);
} else {
println!("Didn't");
}
} else {
println!("Didn't");
}
// Would be replaced with
if let Some(op) = op_op &&
Some(i) = op {
println!("Matched {:?}, {:?}!", op, i);
} else {
println!("Didn't");
}
let (op1, op2) = (Some(7), Some(8));
// If `&&` is allowed, `||` shoud be also. Take first branch that
// destructures. Otherwise do nothing.
if let Some(i) = op1 ||
Some(i) = op2 {
println!("Matched {:?}!", i);
}
// Is equivalent to:
if let Some(i) = op1 {
println!("Matched {:?}!", i);
else if let Some(i) = op2 {
println!("Matched {:?}!", i);
}
// This is invalid because either `i` or `j` might appear in the
// expression. The destructuring must use the same identifiers.
if let Some(i) = op1 ||
Some(j) = op2 {
println!("Matched {:?}!", i);
}
// Adding an `else` clause:
if let Some(i) = op1 {
println!("Matched {:?}!", i);
else if let Some(i) = op2 {
println!("Matched {:?}!", i);
} else {
println!("Didn't");
}
// Would be equivalent to:
if let Some(i) = op1 ||
Some(i) = op2 {
println!("Matched {:?}!", i);
} else {
println!("Didn't");
}
// These can go really deep:
let op_by_4 = Some(Some(Some(Some(6))));
// Would be either:
if let Some(op_by_3) = op_by_4 {
if let Some(op_by_2) = op_by_3 {
if let Some(op) = op_by_2 {
if let Some(i) = op {
println!("Matched {:?}, {:?}, {:?}, {:?}, {:?}!",
op_by_4, op_by_3, op_by_2, op, i);
}
}
}
}
if let Some(op_by_3) = op_by_4 &&
Some(op_by_2) = op_by_3 &&
Some(op) = op_by_2 &&
Some(i) = op {
println!("Matched {:?}, {:?}, {:?}, {:?}, {:?}!",
op_by_4, op_by_3, op_by_2, op, i);
}
}
Technically, &&
is typically used with bool
so &
or some other identifier (and
?) could be valid here as well. I thought &&
made sense though because this is being interpreted in a slightly similar fashion to a boolean expression.
EDIT: Added else
to examples and an example of a deeper nesting example.