基本型 ポインタ
1.84.0 · Source
pub fn addr(self) -> usizeポインタの「アドレス」部分を取得する。
これは
self as usizeと似ているが、ポインタの起源が破棄され公開されない点において異なる。これが意味するのは、戻されたアドレスをキャストして再びポインタにすると起源のないポインタが生成され、その逆参照は未定義動作になるという事実だ。失われた情報を復元して逆参照可能なポインタを適切に得るには、with_addrかmap_addrを使え。もしこれらの API の使用が不可能、つまり必須となる起源つきのポインタを維持する手段がない場合、厳密な起源は適さないかもしれない。代わりにポインタ整数間のキャストまたは
expose_provenanceとwith_exposed_provenanceを使え。ただし、これらはコードに移植性の低下と Rust メモリモデルの順守をチェックするツールとの親和性の低下をもたらしてしまう。殆どのプラットフォームではバイト列全体でアドレスを表現するため、これは元のポインタと同じバイト列の値を生成するだろう。ポインタ内に追加情報を保存する必要のあるプラットフォームはポインタのアドレス部分のみを含む値を生成するために表現の変更を行うかもしれない。それが何を意味するかはプラットフォームでの定義による。
これは厳密な起源の API である。
1.84.0 · Source
pub fn expose_provenance(self) -> usizeポインタの「起源」の部分を後で
with_exposed_provenanceで使えるように公開しつつその「アドレス」の部分を戻す。これは
self as usizeと等価であり、それは意味論的に起源の情報を破棄する。さらに、これは (asキャストのように) 起源を ‘公開’ とマークする暗黙の副作用を持ち、そのためそれをサポートするプラットフォームにおいて後でwith_exposed_provenanceを呼ぶと起源を含んだ元のポインタを再構成できる。その本質的な曖昧さのために、
with_exposed_provenanceは Rust のメモリモデルに継続的に準拠するのを補助するツールによりサポートされないかもしれない。可能な限りはwith_addrのような 厳密な起源の API を使用するのが推奨され、その場合はaddrがexpose_provenanceの代わりに使われるべきである。殆どのプラットフォームでは、元のポインタのバイト列全体をアドレス表現に利用しているので、これはそれと同じバイト列を生成する。ポインタに追加情報の保存が必要なプラットフォームでは、
with_exposed_provenanceの作業に要求される ‘公開’ の副作用が利用できない事が多いため、この操作をサポートしないかもしれない。これは公開された起源の API である。
1.84.0 · Source
pub fn with_addr(self, addr: usize) -> *const T与えられたアドレスと
selfの起源で新しいポインタを作成する。これは
addr as *const Tキャストと似ているが、selfの起源を新しいポインタにコピーする。これは単項のキャストの本質的な曖昧さを排除する。これは
wrapping_offsetを使いselfを与えられたアドレスへとオフセットするのと等価であり、そのため機能も制限も同じである。これは厳密な起源の API である。
1.84.0 · Source
pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> *const T
selfの起源を維持しながら、selfのアドレスから新しい値へとマップ操作をする事により新しいポインタを作成する。これは
with_addrの簡易版であり、詳しくはそちらのメソッドを参照されたい。これは厳密な起源の API である。
1.16.0 (const: 1.61.0) · Source
pub const fn wrapping_offset(self, count: isize) -> *const Tラッピング計算方式でポインタに符号つきオフセットを加える。
countは T を単位とする; つまり、countが 3 なら3 * size_of::<T>()バイトのポインタのオフセットを表す。安全性
この操作自身は安全だが、結果のポインタの使用はそうでない。
結果のポインタは
selfが指し示す割り当てを「思い出す」(これは「起源」と呼ばれる)。そのポインタは他の割り当てを読み書きするのに使ってはならない。言い換えると、
let z = x.wrapping_offset((y as isize) - (x as isize))はたとえTのサイズが1で且つオーバーフローがなくてもzをyと同じにしない:zは依然としてxが帰属するオブジェクトに帰属し、xとyが同じ割り当ての中を指し示していない限りその逆参照は未定義動作となる。
offsetと比べると、このメソッドは基本的に同じ割り当ての中にいる必要性を遅延させる:offsetはオブジェクトの境界を横断すると直ちに未定義動作となる;wrapping_offsetは単にまだ未定義動作を起こしうるポインタを生成し、関連付けられたオブジェクトの領域外でポインタが逆参照された時に問題とする。offsetはより最適化しやすいためパフォーマンスに敏感なコードでは好まれる。遅延チェックはポインタの逆参照されたポインタの値のみを考慮し、最終結果の計算中に使われる中間値は気にしない。例えば、
x.wrapping_offsetは常に(o) .wrapping_offset (o. wrapping_neg ()) xと同じになる。言い換えると、割り当てから離れて後で再び入るのは許可されている。例
// Iterate using a raw pointer in increments of two elements let data = [1u8, 2, 3, 4, 5]; let mut ptr: *const u8 = data.as_ptr(); let step = 2; let end_rounded_up = ptr.wrapping_offset(6); let mut out = String::new(); while ptr != end_rounded_up { unsafe { write!(&mut out, "{}, ", *ptr)?; } ptr = ptr.wrapping_offset(step); } assert_eq!(out.as_str(), "1, 3, 5, ");1.75.0 (const: 1.75.0) · Source
pub const fn wrapping_byte_offset(self, count: isize) -> *const Tラッピング計算方式でポインタに符号つきオフセットをバイト単位で加える。
countはバイト単位である。これは
u8ポインタにキャストしてそれのwrapping_offsetを使うのに純粋に便利である。ドキュメントはそちらを参照されたい。
Sizedでないポイント対象ではこの操作はデータポインタのみを変更し、メタデータには手をつけない。
1.26.0 (const: 1.61.0) · Source
pub const fn wrapping_add(self, count: usize) -> *const Tラッピング計算方式でポインタに符号なしオフセットを加える。
countは T を単位とする; つまり、countが 3 なら3 * size_of::<T>()バイトのポインタのオフセットを表す。安全性
この操作自身は安全だが、結果のポインタの使用はそうでない。
結果のポインタは
selfが指し示す割り当てを 「思い出す」; そのポインタは他の割り当てを読み書きするのに使ってはならない。言い換えると、
let z = x.wrapping_add((y as usize) - (x as usize))はたとえTのサイズが1で且つオーバーフローがなくてもzをyと同じにしない:zは依然としてxが帰属するオブジェクトに帰属し、xとyが同じ割り当ての中を指し示していない限りその逆参照は未定義動作となる。
addと比べると、このメソッドは基本的に同じ割り当ての中にいる必要性を遅延させる:addはオブジェクトの境界を横断すると直ちに未定義動作となる;wrapping_addは単にまだ未定義動作を起こしうるポインタを生成し、関連付けられたオブジェクトの領域外でポインタが逆参照された時に問題とする。addはより最適化しやすいためパフォーマンスに敏感なコードでは好まれる。遅延チェックはポインタの逆参照されたポインタの値のみを考慮し、最終結果の計算中に使われる中間値は気にしない。例えば、
x.wrapping_addは常に(o) .wrapping_sub (o) xと同じになる。言い換えると、割り当てから離れて後で再び入るのは許可されている。例
// Iterate using a raw pointer in increments of two elements let data = [1u8, 2, 3, 4, 5]; let mut ptr: *const u8 = data.as_ptr(); let step = 2; let end_rounded_up = ptr.wrapping_offset(6); let mut out = String::new(); while ptr != end_rounded_up { unsafe { write!(&mut out, "{}, ", *ptr)?; } ptr = ptr.wrapping_offset(step); } assert_eq!(out.as_str(), "1, 3, 5, ");1.75.0 (const: 1.75.0) · Source
pub const fn wrapping_byte_add(self, count: usize) -> *const Tラッピング計算方式でポインタに符号なしオフセットをバイト単位で加える。
countはバイト単位である。これは
u8ポインタにキャストしてそれのwrapping_addを使うのに純粋に便利である。ドキュメントはそちらを参照されたい。
Sizedでないポイント対象ではこの操作はデータポインタのみを変更し、メタデータには手をつけない。1.26.0 (const: 1.61.0) · Source
pub const fn wrapping_sub(self, count: usize) -> *const Tラッピング計算方式でポインタに符号なしオフセットを加える。
countは T を単位とする; つまり、countが 3 なら3 * size_of::<T>()バイトのポインタのオフセットを表す。安全性
この操作自身は安全だが、結果のポインタの使用はそうでない。
結果のポインタは
selfが指し示す割り当てを 「思い出す」; そのポインタは他の割り当てを読み書きするのに使ってはならない。言い換えると、
let z = x.wrapping_sub((x as usize) - (y as usize))はたとえTのサイズが1で且つオーバーフローがなくてもzをyと同じにしない:zは依然としてxが帰属するオブジェクトに帰属し、xとyが同じ割り当ての中を指し示していない限りその逆参照は未定義動作となる。
subと比べると、このメソッドは基本的に同じ割り当ての中にいる必要性を遅延させる:subはオブジェクトの境界を横断すると直ちに未定義動作となる;wrapping_subは単にまだ未定義動作を起こしうるポインタを生成し、関連付けられたオブジェクトの領域外でポインタが逆参照された時に問題とする。subはより最適化しやすいためパフォーマンスに敏感なコードでは好まれる。遅延チェックはポインタの逆参照されたポインタの値のみを考慮し、最終結果の計算中に使われる中間値は気にしない。例えば、
x.wrapping_addは常に(o) .wrapping_sub (o) xと同じになる。言い換えると、割り当てから離れて後で再び入るのは許可されている。例
// Iterate using a raw pointer in increments of two elements (backwards) let data = [1u8, 2, 3, 4, 5]; let mut ptr: *const u8 = data.as_ptr(); let start_rounded_down = ptr.wrapping_sub(2); ptr = ptr.wrapping_add(4); let step = 2; let mut out = String::new(); while ptr != start_rounded_down { unsafe { write!(&mut out, "{}, ", *ptr)?; } ptr = ptr.wrapping_sub(step); } assert_eq!(out, "5, 3, 1, ");1.75.0 (const: 1.75.0) · Source
pub const fn wrapping_byte_sub(self, count: usize) -> *const Tラッピング計算方式でポインタに符号なしオフセットをバイト単位で加える。
countはバイト単位である。これは
u8ポインタにキャストしてそれのwrapping_subを使うのに純粋に便利である。ドキュメントはそちらを参照されたい。
Sizedでないポイント対象ではこの操作はデータポインタのみを変更し、メタデータには手をつけない。