Skip to content

Commit 1d0ae3d

Browse files
committed
core: Implement From<T> for Option<T>
This allows improved ergonomics for functions that have optional parameters: instead of taking `Option<T>`, they can have a type parameter bounded by `Into<Option<T>>`. That way, a value of type `T` can be passed directly without being wrapped by `Some`. As an example, a function fn foo<T>(required: i32, optional: T) -> i32 where T: Into<Option<i32>> { required + optional.into().unwrap_or(0) } can be called as `foo(2, None)` or as `foo(2, 3)`. Refs rust-lang/rfcs#1402
1 parent f01bb5e commit 1d0ae3d

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/libcore/option.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
use self::Option::*;
143143

144144
use clone::Clone;
145+
use convert::From;
145146
use default::Default;
146147
use iter::ExactSizeIterator;
147148
use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator};
@@ -710,6 +711,14 @@ impl<T> Default for Option<T> {
710711
fn default() -> Option<T> { None }
711712
}
712713

714+
#[unstable(feature = "option_from", reason = "recently added", issue = "0")]
715+
impl<T> From<T> for Option<T> {
716+
#[inline]
717+
fn from(t: T) -> Option<T> {
718+
Some(t)
719+
}
720+
}
721+
713722
#[stable(feature = "rust1", since = "1.0.0")]
714723
impl<T> IntoIterator for Option<T> {
715724
type Item = T;

src/libcoretest/option.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,28 @@ fn test_cloned() {
270270
assert_eq!(opt_ref_ref.clone().cloned(), Some(&val));
271271
assert_eq!(opt_ref_ref.cloned().cloned(), Some(1));
272272
}
273+
274+
#[test]
275+
fn test_from() {
276+
assert_eq!(Some(3), Option::from(3));
277+
}
278+
279+
#[test]
280+
fn test_into_optional_parameters() {
281+
use core::convert::Into;
282+
fn myfunc<T, U, V>(t: T, u: U, v: V) -> Option<u8>
283+
where T: Into<Option<u8>>,
284+
U: Into<Option<u8>>,
285+
V: Into<Option<u8>> {
286+
match (t.into() ,u.into(), v.into()) {
287+
(Some(t), Some(u), Some(v)) => Some(t + u + v),
288+
_ => None,
289+
}
290+
}
291+
292+
assert_eq!(None, myfunc(None, 2, 3));
293+
assert_eq!(None, myfunc(1, None, 3));
294+
assert_eq!(None, myfunc(1, 2, None));
295+
assert_eq!(Some(6), myfunc(1, 2, 3));
296+
assert_eq!(Some(6), myfunc(Some(1), Some(2), Some(3)));
297+
}

0 commit comments

Comments
 (0)