2017-03-11 2 views
2

I가 기본적으로 다음과 같이 &[&Path]을 받아 Vec<PathBuf>과 기능을 반환 기능 :Vec <PathBuf> & [& Path] 할당하지 않았습니까?

use std::path::{Path, PathBuf}; 

fn f(paths: &[&Path]) { 
} 

fn main() { 
    let a: Vec<PathBuf> = vec![PathBuf::from("/tmp/a.txt"), PathBuf::from("/tmp/b.txt")]; 

    f(&a[..]); 
} 

는 메모리 할당없이 &[&Path]Vec<PathBuf>을 변환 할 수 있습니까?

그렇지 않은 경우 PathPathBuf으로 슬라이스를 허용하도록 f 서명을 어떻게 변경해야합니까?

+0

'f'를'fn f (경로 : & [PathBuf])'로 변경할 수 없습니까? 아직 슬라이스를 허용하고 있으므로 추가 할당이 필요하지 않습니다. –

+0

@PeterHall 서명이'f' 인 우발적 인 것이 아니라,'Vec <&Path>'도 전달합니다. – user1244932

+3

Path, PathBuf, Vec 및 []에 대해 일반화하려는 경우 'T, I where T : Iterator , I : AsRef ' – the8472

답변

4

Vec<PathBuf>&[&Path]으로 메모리 할당없이 변환 할 수 있습니까?

아니요, 답변 : How do I write a function that takes both owned and non-owned string collections?; PathBufPath은 메모리 레이아웃이 다릅니다 (대답은 Stringstr이며 개념은 같습니다).

는 어떻게 PathPathBuf와 조각을 받아 들일 수 f 서명을 변경해야합니까? How do I write a function that takes both owned and non-owned string collections?에 제안

다시 AsRef를 사용 :이 추가 힙 할당을 필요로하지

use std::path::{Path, PathBuf}; 

fn f<P>(paths: &[P]) 
    where P: AsRef<Path> 
{} 

fn main() { 
    let a = vec![PathBuf::from("/tmp/a.txt")]; 
    let b = vec![Path::new("/tmp/b.txt")]; 

    f(&a); 
    f(&b); 
} 

.

0

슬라이스를 전달하려면 원본 데이터를 어딘가에 보관해야합니다. &[&Path]을 가지려면 Vec<&Path>과 같은 것을 가리켜 야합니다. 하지만 당신은 그 중 하나가 없어, 당신은 Vec<PathBuf> 있습니다.

기존 서명을 사용하려면 임시 Vec<&Path>을 만든 다음 조각을 찍을 수 있습니다. 이 새로운 Vec을 생성하더라도

fn f(paths: &[&Path]) { 
} 

fn main() { 
    let a: Vec<PathBuf> = vec![PathBuf::from("/tmp/a.txt"), PathBuf::from("/tmp/b.txt")]; 
    let paths: Vec<&Path> = a.iter().map(PathBuf::as_path).collect(); 
    f(&paths[..]); 

} 

,이 스택 포인터에 지나지 않는다 - 실제로 경로 중 하나를 복사 할 필요가 없습니다.

+0

크기는 내 견해와 관련이 없지만 할당 힙에 많은 시간이 필요할 수 있습니다. 반복자 (거의 당신의 코드와 비슷하지만'collect'가 없다)로 슬라이스를 변경하는 것에 대해 생각했지만, 크기 매직 때문에 컴파일러가 내 코드를 받아들이도록 강요 할 수는 없습니다. – user1244932

+0

여기에 새로운 힙 할당이 없습니다. 기존 경로에 대한 참조 만 –

+0

'let paths : Vec <&Path>'그래서'Vec'가 스택에 장소를 할당한다고 알려주시겠습니까? – user1244932

0

할당하지 않고 캐스팅하는 것은 메모리의 레이아웃이 다르기 때문에 불가능합니다.

Vec<PathBuf>은 데이터를 인라인으로 저장하고 [&Path]은 데이터에 대한 포인터를 저장합니다 (대략 Vec<&PathBuf>과 유사 함).

포인터를 저장할 새 벡터를 만들어야합니다. 크기가 컴파일 타임에 알려졌다면 스택에 할당 된 배열을 사용할 수 있습니다. 그렇지 않으면 map + collect이 필요합니다.