2017-11-30 5 views
0

내 코드에는 구조체가 많이 있는데 Option<T>이 들어 있습니다. 나는 많은 곳에서 그것들과 함께 작업해야하기 때문에 코드가 car.engine.as_ref().unwrap()과 같은 구조체 액세스로 흩어져있다. 이것은 코드 가독성을위한 고통입니다.as_ref(). unwrap()에 대한 바로 가기가 있습니까?

동일한 기능을 수행하는 Option<T> 유형의 기본 기능이 있습니까? car.engine.get()처럼? 물론 모든 구조체 멤버에 대해 접근 자 함수를 작성할 수는 있지만 이는 너무 기본적인 것에 대한 과도한 것처럼 보입니다. 내가 잘못하고 있니?

매크로에 대해 많이 알지는 못하나 매크로를 사용하여 매크로를 줄이는 방법이 있습니까?

답변

5

당신을 활용 할 수 있습니다

if let Some(ref e) = car.engine { println!("foo {}", e.serial); } 
else { println!("nope"); } 

그렇지 않으면, 당신은 쉽게 확장 특성에 자신의 기능 덕분에 쓸 수 있습니다 (녹 1.22 이후) (이 Result<T, E>로하는 것처럼)도 Option<T> 유형으로 작동 ? 운영자 :

struct Foo; 

struct Bar { 
    foo: Option<Foo>, 
    // other optional fields 
} 

impl Bar { 
    fn use_optional_fields(&self) -> Option<&Foo> { 
     let foo = self.foo.as_ref()?; 
     // use optional fields 
     Some(foo) 
    } 
} 
+0

사실, 해당 기능은 [이미 사용 가능] (https://blog.rust-lang.org/2017/11/22/Rust-1.22.html)입니다. –

+0

@ E_net4 감사합니다. – ljedrz

+0

이것은 다른 대답보다 더 관용적 인 것 같습니다. 그래서 이것을 점검하겠습니다. 두 대답 모두 정말 좋습니다. – itmuckel

4

어쨌든 unwrap은 일반적으로 권장되지 않으므로 그다지 놀라운 것을 발견 할 수 없습니다. 오류의 경우를 처리하려는 경우, 당신은이 작업을 수행 할 수 있습니다

trait OptionExt { 
    type Value; 
    fn unwrap_ref(&self) -> &Self::Value; 
    fn unwrap_mut(&mut self) -> &mut Self::Value; 
} 

impl <T> OptionExt for Option<T> { 
    type Value = T; 
    fn unwrap_ref(&self) -> &T { self.as_ref().unwrap() } 
    fn unwrap_mut(&mut self) -> &mut T { self.as_mut().unwrap() } 
} 

// Now you can write 
let e = car.engine.unwrap_ref(); 
+0

매우 가치있는 정보를 제공합니다. 기본 유형을 확장 할 수 있는지 알지 못했습니다. – itmuckel

관련 문제