다른 구문 분석 함수를 전달하고 다른 Iteratee
을 얻을 수 있도록 Iteratee
구조를 일반화하려고합니다.HKT (Higher kinded type) 지원없이 Rust에서 일반 구조를 만들려면 어떻게해야합니까?
use std::io::{BufRead, BufReader};
use std::str::{from_utf8, Utf8Error};
#[derive(PartialEq, Debug)]
struct Cat<'a> {
name: &'a str,
}
fn parse<'a>(slice: &'a [u8]) -> Result<Cat<'a>, Utf8Error> {
from_utf8(slice).map(|name| Cat { name: name })
}
struct Iteratee<R>
where R: BufRead + Sized
{
read: R,
}
impl<R> Iteratee<R>
where R: BufRead + Sized
{
fn next<'a, F>(&'a mut self, fun: F)
where F: Fn(Option<Result<Cat<'a>, Utf8Error>>) ->() + Sized
{
let slice = self.read.fill_buf().unwrap();
fun(Some(parse(slice)))
// ^^^^^^^^^^^ How do I pull 'parse' up as a function of Iteratee
}
}
fn main() {
let data = &b"felix"[..];
let read = BufReader::new(data);
let mut iterator = Iteratee { read: read };
iterator.next(|cat| assert_eq!(cat.unwrap().unwrap(), Cat { name: "felix" }));
}
이 그것이 일반적인 제작에서 내 시도,하지만 난이 함수에 대한 참조 또는 폐쇄를 전달하거나 함께 IterateeFun
을 만들 수 없습니다 :이 작품이 아닌 일반 버전입니다.
struct IterateeFun<R, P, T>
where R: BufRead + Sized,
P: Fn(&[u8]) -> (Result<T, Utf8Error>) + Sized
{
read: R,
parser: P,
}
impl<R, P, T> IterateeFun<R, P, T>
where R: BufRead + Sized,
P: Fn(&[u8]) -> (Result<T, Utf8Error>) + Sized
{
fn next<'a, F>(&'a mut self, fun: F)
where F: Fn(Option<Result<T, Utf8Error>>) ->() + Sized
{
let slice = self.read.fill_buf().unwrap();
fun(Some((self.parser)(slice)))
}
}
fn main() {
let data = &b"felix"[..];
let read = BufReader::new(data);
let mut iterator = IterateeFun {
read: read,
parser: parse, // What can I put here?
// I've tried a closure but then I get error[E0495]/ lifetime issues
};
iterator.next(|cat| assert_eq!(cat.unwrap().unwrap(), Cat { name: "felix" }));
}
그림과 같이 함수에 함수를 전달하는 방법을 알고 싶습니다. 아니면 내가 대신이 특성으로해야합니까?
입니다. 오류 [E0495]는 실제 문제가 아니며, 함수를 전달하거나 최소한 코드의 제네릭 버전을 만들 수있는 방식으로 코드를 재구성하는 방법입니다. 어쩌면 나는 관용적 인 녹 방법으로 이것을 생각하지 않을 것입니다. 이것은 내가 특성에 대한 언급으로 언급하려고했던 것입니다. 요약하면 내가 모르는 것을 알지 못합니다.) –
[녹스에 클로저를 저장하는 방법은 무엇입니까?] (http://stackoverflow.com/q/27831944/155423), [저장 중 HashMap의 클로저] (http://stackoverflow.com/q/29202137/155423) 또는 [구조에 클로저 저장 - 적절한 평생을 추론 할 수 없음] (http://stackoverflow.com/q/21510694/) 155423) (특별히 검토하지는 않았지만 초기 검색 결과 일뿐입니다). – Shepmaster
[higher-rank trait bounds] (https://doc.rust-lang.org/beta/nomicon/hrtb.html)를 사용하는 답변을 게시했습니다. [예 : 놀이터에서보기] (https : // gist .github.com/07a68fd62b03ae54659716e118d2b1da). 그러나 여전히 두 번째 스 니펫만큼 일반적이지는 않습니다. 클로저가 'T <'a>'이 아니라 'Result'을 반환한다고 가정합니다. 후자가 [더 높은 종류의 유형]이없는 현재 녹에서 표현하는 것이 불가능할 수도 있습니다 (https://users.rust-lang.org/t/does-rust-really-need-higher). -kinded-types/5531). 이것이 타입 시스템에 대한 나의 이해를 넘어선 것처럼, 나는 나의 대답을 제거했다. –
user4815162342