2017-01-30 2 views
1

나는 구조체가있다. 녹 구조체의 참조 필드에는 평생 매개 변수가 필요하므로 문제가 발생합니다. C 지금이어야한다 :평생을 추가 할 때 모든 다운 스트림 구조체에 수명을 추가하지 않는 방법이 있습니까?</p> <pre><code>struct C { field: Box<Fn()> } struct D(C) struct E(C) struct F(D) </code></pre> <p>내가라는 이름의 기능을 수용 할 수 <code>C</code> 대신 <code>&Fn()</code>의 분야를 변경하려면 :

struct C<'a> { 
    field: &'a Fn() 
} 

그런 D, E, F, 나는뿐만 아니라 수명 매개 변수를 제공해야 :

struct D<'a>(c<'a>) 
struct E<'a>(C<'a>) 
struct F<'a>(C<'a>) 

D, E, F 많은 impl 기능을 가지고 상상 ... 이제 코드는 많은 장소에 평생 매개 변수를 추가하기 위해 대규모 변경이 필요합니다.

그렇게하지 않는 방법이 있습니까? C의 수명 매개 변수는 'static 일 수 없으며 로컬로 정의 된 클로저도 있습니다.

답변

2

피할 수있는 아주 간단한 방법이 있습니다. 일반 기능으로는 Box<Fn()>도 사용하십시오.

  • fn() 그래서 Box<Fn()> 당신이 모두를 가질 수 있도록 사용 "간단한"기능
  • Fn() 두 기능을 통해 초록 및 폐쇄

을 나타냅니다

녹 추상화 된 기능의 두 가지 유형이 있습니다.

"naked"기능에는 불필요한 메모리 할당이 있습니다. 전체 코드를 리팩토링하지 않아도되는 대신 트레이드 오프를 받아 들일 수 있습니다.

메모리 할당을 피하려는 경우 Cow을 참조하십시오.

+0

감사합니다. 그리고 또한 설명을 위해 Shipmaster에게 많은 thx. – kkspeed

+0

일반 함수의 크기는 0입니다.복싱 zero-sized 타입은 전혀 할당을 수행하지 않습니다 (할당자는 포인터에 대해 단지'1'을 반환합니다). –

+0

@ FrancisGagné : 확실한가요? 확실히 런타임에는 호출 할 함수를 알 수있는 함수에 대한 포인터가 필요합니다. –

3

Matthieu M. has answered 아마하지만 당신의 질문 당신의 문제를 해결 질문 "어떻게 전혀 평생을 추가 피할 수있다":

이 모든 다운 스트림에 수명을 추가하지 할 수있는 방법이 있나요 평생 추가시 구조체

아니요, 없습니다. 평생 주석은 이며 유형을 매개 변수화 한 다른 일반 유형입니다. 그 유형을 사용하는 모든 것은 매개 변수화 된 구체적인 수명을 알아야합니다. 평생 동안 커다란 이유 중 하나는 안전한 시스템을 갖추기 위해서 컴파일러 (그리고 당신!)가 구조체가 범위를 벗어날 수있는 무언가에 대한 참조를 포함한다는 것을 알아야한다는 것입니다. 그 중 하나가 발생하면 참조가 더 이상 유효하지 않습니다.