Как работать с вариантом и вариант <& T> - PullRequest
0 голосов
/ 28 мая 2020

В этом примере мы предполагаем, что у нас есть два кода, которые имеют свой периметр и тестируются индивидуально.

код 1 возвращает тип Option<Rc<RefCell<T>>> и код 2 которые должны потреблять &T.

У меня проблемы со следующим примером игровая площадка .

use std::cell::RefCell;
use std::rc::Rc;

// Code 2
fn action(data_1: Option<&i32>, data_2: Option<&i32>) {
    println!("data_1:{:?}, data_2:{:?}", data_1, data_2);
}

fn main() {
    // Code 1
    let data_1 = Some(Rc::new(RefCell::new(2)));
    let data_2 = Some(Rc::new(RefCell::new(5)));

    let ref_data_1 = data_1.as_ref().map(|r| r.borrow());
    let ref_data_2 = data_2.as_ref().map(|r| r.borrow());

    action(ref_data_1, ref_data_2); // Error: mismatched types
}

Пример не работает из-за несоответствия типов между Ref<T> найдено и ожидается &T. Мой единственный способ, который я создал, - это изменить Option<&i32> на Option<Ref<i32>>, но это нарушит интерфейс code 2 .

1 Ответ

3 голосов
/ 28 мая 2020

Вы можете изменить функцию action так, чтобы она принимала либо Option<&i32>, или Option<Ref<i32>>, используя аргумент generi c с привязкой Deref<Target = i32>, которой удовлетворяют оба этих типа:

use std::ops::Deref;

fn action<T>(data_1: Option<T>, data_2: Option<T>)
where
    T: Deref<Target = i32>,
{
    println!("data_1:{:?}, data_2:{:?}", data_1.as_deref(), data_2.as_deref());
}

Если вы не можете или не хотите изменять подпись action, вы можете вызвать as_deref() для аргументов при их передаче:

action(ref_data_1.as_deref(), ref_data_2.as_deref());
...