녹:스마트 포인터

7701 단어 rust

포인터


포인터는 메모리에 주소를 포함하는 변수입니다.
그것은 다른 데이터를 가리키거나 인용한다.
너는 그것을 그 값을 가리키는 화살표로 상상할 수 있다.
Rust에는 참조라는 두 가지 일반 유형의 포인터가 있습니다.
그것들은 변수 이름 앞의 기호로 식별된다.
  • &은 가변 참조에 사용됩니다(예: &my_variable).
  • &mut, 가변 인용에 사용됩니다.(예: &mut my_variable)
  • 값에 대한 인용은 이 값을 가지지 않고 이 값을 빌려씁니다.
    다시 말하면 인용은 사라질 수 있고, 인용이 가리키는 값은 여전히 존재한다.

    The Rust programming language book has a great chapter on ownership in Rust.


    Rust의 data race 예방 규칙은 특정 범위의 특정 블록에 대해
    이 데이터에 대해 하나의 가변 인용만 있을 수 있고, 여러 개의 가변 인용도 있을 수 있다.
    영원히 이 두 가지 방법을 동시에 사용하지 마라.
    컴파일러 오류에서 '공유 인용' 이라는 용어를 식별할 수 있습니다.
    얼마 전에 나는 blablabla, because it is behind a shared reference이라고 쓰여 있는 컴파일러 오류를 만났다.
    이것은 나를 매우 곤혹스럽게 했다. 메시지가 프로그램 전체에 인용이 하나밖에 없다는 것을 지시했을 때, 나는 그 오류가 발생했다.
    그럼 어떻게'공유'를 해요?
    많은 상황에서'공유 인용'은'불가변 인용'의 또 다른 표현이라는 사실이 증명되었다.
  • 의 불변 인용의 또 다른 명칭은 공유 인용이다.
  • 가변 인용의 또 다른 명칭은 독점 인용이다.
  • 지능 지침


    이 인용들은 일부 데이터만을 가리키는 일반적인 지침으로, 다른 기능은 없다.
    스마트 포인터는 추가 기능을 할 수 있다.
    그것들은 데이터 구조로 바늘의 역할을 할 뿐만 아니라 추가 메타데이터도 있다.
    그들은 일반적인 지침이 실현할 수 없는 행동을 실현하기 위해 이 추가 데이터를 사용한다.
    그 지침들은...총명했어

    지능 지침은 통상적으로 구조로 이루어진다.
    일반적인 인용과 다른 점은 스마트 포인터가 가리키는 데이터를 가지고 있다는 것이다.
    지능 지침이 버려지면 그들이 가리키는 데이터가 버려진다는 얘기다.
    대부분의 스마트 포인터는 Deref Drop 의 특징을 실현한다.

    꿰미


    만약 이전에 Rust 프로그래밍을 사용한 적이 있다면, 자신이 이미 스마트 포인터를 사용했다는 것을 모르더라도 스마트 포인터를 사용했을 가능성이 높다.
    String 은 스마트 포인터입니다.
    let s1 = String::from("hello");
    
    다음 그림의 왼쪽은 스택에 저장된 데이터입니다.
    오른쪽은 무더기에 저장된 데이터다.

    Psst, I wrote about the stack and the heap in Rust


    창고에는 우리의 String , 이름은 s1이다.
    그것은 더미 위의 특정 위치를 가리키는 지침(ptr중)이 있는 구조이다.
    문자열의 길이 (len에서) 와 문자열이 차지하는 바이트 수 (capacity에서) 와 같은 추가 메타데이터도 있습니다.
    마지막 두 필드 사이의 차이는 현재 중요하지 않다. 중요한 것은 문자열에 이와 관련된 추가 메타데이터가 있다는 것이다.
    이 문자열의 내용을 연속된 메모리 주소에 저장합니다.
    이 예에서 알파벳 h, e, l, l, o, Deref.
    책에서 꺼낸 문자열의 설명도

    Rust 프로그래밍 언어 데리프


    기능은 필드에 바늘을 저장하는 일반적인 구조가 아니라 바늘처럼 작업을 할 수 있도록 합니다.
    이렇게 하면 인용에 적합한 코드를 작성할 수 있고 스마트 포인터도 사용할 수 있다.
    인용 연산자 *을 풀고 그 값을 가리키는 바늘을 따라가세요.
    일반적인 구조상 그것을 호출하는 것은 통하지 않지만, Deref 의 구조를 실현하면 이런 상황이 발생할 때 어떻게 해야 하는지 안다.
    Deref 의 특성을 실현하려면 반드시 deref이라는 방법을 실현해야 한다.
    그것은 self에 대한 불변 인용을 받아들이고 다른 종류의 불변 인용을 되돌려줍니다.

    In my opinion, the deref method is incredibly confusing naming.
    deref doesn't dereference at all, it returns a reference.
    The compiler knows how to dereference that reference.


    Box<T> 유형은 Deref 을 구현하는 스마트 포인터입니다.
    엔진 뚜껑 아래에서 해인용 연산자 a Box<T> 을 사용할 때 먼저 deref 방법을 사용합니다.deref에서 다른 인용을 되돌려줍니다.
    Box<T> 에 대해 내부 유형에 대한 인용으로 T Box<T>이다.
    그리고 컴파일러는 이 인용을 따라 인용을 취소합니다.
    let num = 5;
    let boxed_num = Box::new(num);
    
    assert_eq!(5, num);
    assert_eq!(5, *boxed_num);
    
    첫 번째 assert_eq에서 우리는 5num을 직접 비교했다.
    두 번째 assert_eq에서 우리는 5과 컨테이너 값에 대한 인용 연산자 사용 결과를 비교할 것이다.*boxed_num*(boxed_num.deref())을 쓰는 것과 같다.

    내리다 내리다


    기능은 이 구조의 실례가 범위를 초과할 때 실행되는 코드를 사용자 정의할 수 있습니다.
    그것은 네트워크 연결, 파일, 사용된 메모리 등의 자원을 방출하는 데 쓰인다.
    사용 예: Box<T> 의 소유자가 범위를 초과할 경우Box이 스택에서 튀어나왔을 뿐만 아니라 스택에서 메모리를 사용했던 T도 풀렸다.
    Drop 의 특성을 실현하려면 반드시 drop이라는 방법을 실현해야 한다.
    그것은 self에 대한 가변 인용을 받아들여 어떤 내용도 되돌려주지 않는다.(이것은 단위 유형, 공원조, ()으로 되돌아간다)
    값의 소유자가 범위를 초과하면 drop이 자동으로 호출됩니다.
    다시 말하면 변수가 표시 범위의 권곡bois{}에서 벗어나면 이 변수에 대해 drop을 호출한다.
    drop 트레이트의 Drop 방법을 수동으로 호출할 수 없습니다.
    적어도 직접적인 건 아니야.
    역할 영역에서 이렇게 하면 역할 영역이 끝날 때 이 방법을 다시 자동으로 호출할 수 있습니다.
    이것은 불필요한 상황을 초래하거나 악명 높은 이중 방출 오류를 초래할 수 있다. 즉, 메모리를 두 번 방출하려고 시도하는 것이다.
    범위가 종료되기 전에 drop으로 전화하려면 std::mem::drop 으로 전화하십시오.
    이것은 drop을 한 번만 호출할 수 있도록 확보할 것이다.

    좋은 웹페이지 즐겨찾기