녹:스마트 포인터
포인터
포인터는 메모리에 주소를 포함하는 변수입니다.
그것은 다른 데이터를 가리키거나 인용한다.
너는 그것을 그 값을 가리키는 화살표로 상상할 수 있다.
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
에서 우리는 5
과 num
을 직접 비교했다.두 번째
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
을 한 번만 호출할 수 있도록 확보할 것이다.
Reference
이 문제에 관하여(녹:스마트 포인터), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/nickymeuleman/rust-smart-pointers-2g5g텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)