2015-07-22 2 views
7

Попытка составить следующее,Почему параметры типа не разрешены для этого типа?

fn do_it() -> Result<i32, u32> { 
    Result::<i32, u32>::Ok(3) 
} 


fn main() { 
    println!("{}", do_it()); 
} 

приводит:

./result_test.rs:2:14: 2:17 error: type parameters are not allowed on this type [E0109] 
./result_test.rs:2  Result::<i32, u32>::Ok(3) 
           ^~~ 

Почему параметры типа не допускаются на этот тип?

Это минимальный пример, мой реальный пример макрос пытается вернуть следующее:

match $reader.$read_func() { 
    Ok(n) => Result::<$read_type, LocalReadError>::Ok(n), 
    Err(err) => Result::<$read_type, LocalReadError>::Err(
     LocalReadError::from(err) 
    ), 
} 

$read_func является функцией, $read_type является типом возвращаемого значения этой функции. (Если бы у меня был программный способ получить это, я бы сделал это, я не знаю, как, так что это аргумент ...); as-is, я получаю вышеуказанную ошибку. Если я удалю спецификацию параметров generic, введите inteference, жалуйтесь, что он не может определить тип. (?. Потому что заканчивается Result<_, LocalReadError> в одной ветви match и Result<$read_type, _> в другой я не совсем уверен, что он говорит:

error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282] 
    match $reader.$read_func() { 
        ^~~~~~~~~~~~ 

)

Примечание: Вопрос о том, почему параметры типа не разрешены. Оказывается, это не является причиной того, что «невозможно определить достаточную информацию о типе». (read_func - это функция, в моем случае я передаю шаблонную функцию, но забываю шаблон arg, который не может быть выведен.)

+0

Это выглядит замечательно как ошибка. https://doc.rust-lang.org/nightly/error-index.html#E0109 показывает, что он должен делать. –

+1

как обход вашей реальной проблемы Я предлагаю изменить ваш макрос на '$ reader. $ Read_func(). Map_err (LocalReadError :: from)' –

+2

не уверен, что это ошибка или если это действительно ожидалось, но синтаксис, который работы выглядят так: 'Результат :: Ок :: (3)'. [Манеж] (http://is.gd/xNUV9B) –

ответ

9

Это на самом деле несогласованность с перечислениями, которые was discussed, но не считаются достаточно важными для блокировки 1.0.

Рабочий синтаксис для указания типов: Result::Ok::<i32, u32>(3).

Перечислитель работает как нечто между типом (который будет работать с синтаксисом, который вы пытались записать), и пространство имен (и пространства имен не принимают параметры типа).

Чтобы продемонстрировать, как перечисления, как пространство имен, вы можете написать:

use std::result::Result::*; 

fn main() { 
    println!("{:?}", Ok::<i32, u32>(3)); 
} 

Это Пространство имена аспекта является желательным свойством перечислений, но перемещение параметров типа, где один интуитивно думает, что они должны быть бы сделать этот тип код очень неудобно писать.