2016-11-22 4 views
0

나는 동적으로 녹 구조체로 데이터베이스 결과를 매핑에 대한 Entity 인터페이스를 만들려고 노력하고 있어요 :사용 특성은

error: no method named map found for type T in the current scope
ret.push(query.entity.map(row.unwrap())); |
note: the method map exists but the following trait bounds were not satisfied: T : std::iter::Iterator = help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item map , perhaps you need to implement one of them: = help: candidate #1: models::holders::database::Entity = help: candidate #2: std::iter::Iterator

+1

당신의 예제가 최소한의 예제로는별로 보이지 않지만, 나는'D'가'DbQuery' 나'DbMapper ::'에'Entity'를 구현하도록'T'를 제한하지 않았다고 대답 할 것이라고 생각합니다. 찾기 '. –

+0

죄송합니다. 최소 코드를 사용하여 설명했습니다. 불행히도 T 대신 Entity를 이미 시도했지만 동일한 오류가 발생했습니다. – plailopo

+1

안녕하세요 - 다소 적습니다 만 play.rust-lang.org에 넣고 컴파일하여 동일한 오류가 발생하도록 충분히 완벽하지는 않습니다. 그래서 확신하기가 약간 어렵습니다. –

답변

2

Here is a version of your code that runs on the playground :

pub trait Entity { 
    fn map(&self, Result<QueryResult>) -> Self; 
} 

pub struct DbQuery<T> { 
    pub sql: String, 
    pub params: Vec<Value>, 
    pub limit: i32, 
    pub paged: Option<Pagination>, 
    pub entity: T, 
} 

pub struct Settings { 
    pub name: String, 
    pub value: Option<String>, 
} 

impl Entity for Settings { 
    fn map(&self, result: Result<QueryResult>) -> Settings { 
     // ... 
     Settings { 
      name: "hello".to_string(), 
      value: None, 
     } 
    } 
} 

impl DbMapper { 
    // ... 

    pub fn find<T>(&self, query: DbQuery<T>) -> Option<Vec<T>> { 
     println!("query find SQL: {}", query.sql); 
     let mut stmt = &self.pool.prepare(query.sql).unwrap(); 
     let ret = Vec::new(); 
     for row in stmt.execute(query.params).unwrap() { 
      ret.push(query.entity.map(row.unwrap())); 

     } 

     Some(ret) 
    } 
} 

하지만 오류가 발생 문제를 복제합니다.

pub struct QueryResult; 
pub struct Value; 
pub struct Pagination; 
pub struct DbMapper; 

pub trait Entity { 
    fn map(&self, Result<QueryResult,()>) -> Self; 
} 

pub struct DbQuery<T> { 
    pub sql: String, 
    pub params: Vec<Value>, 
    pub limit: i32, 
    pub paged: Option<Pagination>, 
    pub entity: T, 
} 

pub struct Settings { 
    pub name: String, 
    pub value: Option<String>, 
} 

impl Entity for Settings { 
    fn map(&self, result: Result<QueryResult,()>) -> Settings { 
     // ... 
     Settings { 
      name: "hello".to_string(), 
      value: None, 
     } 
    } 
} 

impl DbMapper { 
    // ... 

    pub fn find<T>(&self, query: DbQuery<T>) -> Option<Vec<T>> { 
     println!("query find SQL: {}", query.sql); 

     // ########## attempt to call map() 
     let _ = query.entity.map(Ok(QueryResult {})); 

     let ret = Vec::new(); 
     Some(ret) 

    } 
} 

fn main() {} 

문제는입니다. find 메서드에서 DbQuery<T> 인수의은 TEntity 유형임을 알 수 없습니다. 그래서 우리는 그것을 말할 필요가 있습니다 :

pub fn find<T>(&self, query: DbQuery<T>) -> Option<Vec<T>> 
    where T: Entity 
{ 
    // ... code here ... 
} 

This now compiles and runs.

이제 컴파일러는 T이 어떤 설명 인 Entity이라는 것을 알고 있으며 map 메서드를 호출 할 수 있습니다.

+0

예! 고맙습니다. 나는 녹에 새로운 새끼 야. 그러나 T 대신 Entity를 사용하지 않는 이유는 무엇입니까? – plailopo

+0

왜냐하면'T'는 당신이 그것을 명시 적으로 줄 때까지는 그 방법에 문맥이 없기 때문입니다. 컴파일러의 관점에서, 당신은 "여기에 타입 T가 있습니다. 그것은 어떤 타입이든 될 수 있습니다."라고 말했습니다. 컴파일러는 그 타입이 map 메소드를 구현한다는 것을 알 수 없다. 엔티티 유형이라는 힌트를 제공함으로써 컴파일러는 맵을 호출 할 수 있음을 알고 있습니다. –