2015-06-11 2 views
2

ЭтоНесовпадение в количестве/Типы аргументов

extern crate postgres; 

use postgres::{Connection, SslMode}; 

struct User { 
    reference: String, 
    email: String, 
    firstname: String, 
    lastname: String 
} 

static DB_URI: &'static str = "postgres://postgres:[email protected]/test"; 

fn main() { 

    let conn = Connection::connect(DB_URI, &SslMode::None).unwrap(); 
    let trans = conn.transaction().unwrap(); 

    //... 

} 

fn insert_user<'a>(trans: &'a postgres::Transaction, user: &User) -> &'a postgres::Result { 
    //... 
} 

бросает ошибку

error: wrong number of type arguments: expected 1, found 0 [E0243] 
fn insert_user<'a>(trans: &'a postgres::Transaction, user: &User) -> &'a postgres::Result { 
                     ^~~~~~~~~~~~~~~~ 

Что здесь отсутствует? Я просто хочу вернуть результат выполненного запроса.

UPDATE Так я изменил функцию строку:

fn insert_user(trans: &postgres::Transaction, user: &User) -> &postgres::Result<()> { 

обмануть компилятор в выявлении правильного типа возвращаемого и он дал мне это:

mismatched types: 
expected `core::result::Result<(), postgres::error::Error>`, 
    found `core::result::Result<postgres::Rows<'_>, postgres::error::Error>` 

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

fn insert_user(trans: &postgres::Transaction, user: &User) -> &postgres::Result<postgres::Rows<'_>, postgres::error::Error> { 

это теперь бросает новую ошибку:

error: use of undeclared lifetime name `'_` [E0261] 
fn insert_user(trans: &postgres::Transaction, user: &User) -> postgres::Result<postgres::Rows<'_>, postgres::error::Error> { 
                           ^~ 
+2

Это именно то, что он говорит. Вы указали неверное количество аргументов типа. ['Result'] (http://sfackler.github.io/rust-postgres/doc/v0.9.1/postgres/type.Result.html) принимает тип возвращаемого действительного значения. – Veedrac

ответ

4

Глядя на documentation для обрешетки postgres, мы можем видеть, что тип postgres::Result является общим над один аргументом типа:

type Result<T> = Result<T, Error>; 

Обычно вы бы два варианта:

  1. указать тип если вы знаете, что это такое: postgres::Result<MyType>
  2. Позвольте компилятору сделать это для вас (если у него достаточно информации в другом месте): postgres::Result<_>

Однако в обратном типе (что происходит после ->) вывод типа не запускается, поэтому доступен только вариант 1.

(Подсказка:. Вы еще один трюк в рукаве, чтобы узнать нужный тип можно попробовать указать тип блока: ... -> postgres::Result<()> и проверить, если компилятор жалуется с ошибкой, например, как «ожидается MyType, нашел ()». Это означает, что вы хотите указать ... -> postgres::Result<MyType>.)

+0

Спасибо за трюк совет, сделал некоторый прогресс с ним, но компилятор все еще жалуется, я уверен, что есть причина. – Caballero

+1

Я бы посоветовал восстановить время жизни '' a' вам и использовать его вместо '' _', поскольку компилятор не выводит его. –

+0

@Caballero действительно вы пошли на один шаг слишком далеко, копируя сообщение об ошибке, потому что '' _ - анонимное время жизни, и не рекомендуется, чтобы вы написали пожизненный '' _'. Обычно они называются '' a' или '' b'. Увидев [ваш второй вопрос подряд] (http://stackoverflow.com/questions/30784279/rust-borrowed-value-does-not-live-long-enough), я предлагаю, что, возможно, вы хотите приостановить написание кода для немного узнать и узнать язык с помощью [Rust book] (https://doc.rust-lang.org/book) (в частности, раздел [lifetime] (https: //doc.rust-lang. орг/книга/lifetimes.html)). – mdup

2

Result определяется как postgres::Result<T> (мы говорим, что родовое над Т). В зависимости от внутренних функций функции insert_user это может быть Result<bool>, Result<u64>, Result<()> или что-то еще влезло.

Например, метод execute на Transaction возвращает Result<u64>, так что это вероятный вариант.