2014-11-15 3 views
1

평생 주석이있는 구조체를 내보내는 라이브러리가 있습니다. 이제 다른 프로그램에서이 프로그램을 사용하려고했지만, 이제 평생 주석을 사용해야 할 것 같습니다. 기본적으로 나는이 일을 해요 :평생 주석 또는 & str vs String

BarFoo을 위해 평생을 정의해야한다고
// in my lib 
struct Foo<'a> { 
    baz: &'a str 
} 

// another program 
struct Bar { 
    foo: Foo 
} 

:

<anon>:6:10: 6:13 error: wrong number of lifetime parameters: expected 1, found 0 [E0107] 
<anon>:6  foo: Foo 
        ^~~ 

이 해결하기 쉽습니다 :

struct Bar<'a> { 
    foo: Foo<'a> 
} 

을하지만이 지금을 의미 Bar 등을 사용하는 모든 기기의 수명을 정의해야합니다. 그리고 이것이 사실이라면 명시 적 수명이 필요하지 않은 유형을 사용하는 것 외에는이를 해결할 수있는 방법이 있습니까? 또는 String과 같은 소유 유형을 사용하는 것이 더 낫지 않습니까?

배경이 약간이지만, 인수로 필요한 함수를 호출해야했기 때문에 &str을 사용했습니다. 그들을 변환하는 동안 아무 문제가, 실제로는 Vec<(&str, &str)>, 그래서 내 생각은 처음부터 올바른 유형을 사용하여 전환을 제거하는 것이었다. 나는 잘못된 결정이라는 느낌을 가지고 있지만, 내가 아는 것은 무엇입니까? :)

+0

녹에는 "저렴한"전환이 있습니다. 관습에 따라 'as_'로 시작하는 메소드 이름으로 표시됩니다. 예를 들어'String :: as_slice'는'string '을 빌려 오는'& str'을 생성합니다. –

답변

4

예 현재 명시적인 수명이 버블 링되는 것을 방지 할 방법이 없습니다. 그것에 대해 생각하는 방법은 baz 필드가 종속되어 있기 때문에 Foo에 어떤 수명이 관련되어 있는지 명시해야하기 때문에 예를 들어 Foo을 더 길게 만들려고하면 컴파일러에서 멈추는 것을 알고 있습니다. 데이터 baz을 참조하거나, "baz가 살아있을 때만 존속하는"참조를 반환하는 메소드를 가질 수 있습니다. 그런 다음 FooBar에 삽입하면 Foo이 종속되어 있으므로 이제 Bar에 명시적인 유효 기간이 필요합니다. Foo 만약

는 다음이 참으로 String해야하는 Foo이 가능한 수명 (예를 들어 범위)의 독자적에 서 할 수 있어야하는 경우 즉, 문자열을 "소유"입니다. String에서 슬라이스로 변환하는 것은 슬라이스가 기존 데이터의 뷰에 불과하기 때문에 매우 저렴합니다.

그러나 경우 항상이 범위에 연결되어 기존 데이터를 기반으로 Foo를 구성하는 것 (예를 들면 Foo 인스턴스를 포함하는 기능 등에 전달 된 문자열 조각)와 Foo 인스턴스는 '아무튼 기존 데이터의 범위를 벗어나서 살아야한다면, String을 만든 경우 String (반대로 상대적으로 비쌉니다)으로 변환해야만 슬라이스로 다시 변환해야합니다. 사용 시점은 슬라이스로 유지해야합니다. 명시 적 수명을 입력하지 않아도되므로이 성능 저하가 발생하지 않아야합니다.

명시 적 수명이있는 유형은 매우 일반적이므로 처음에는 놀랄 것 같지만 익숙해집니다.

관련 문제