&[T]
меня смущает.
Я наивно полагал, что подобный &T
, &[T]
был указателем, то есть числовым указательным адресом.
Тем не менее, я видел некоторый код, похожий на этот, что я был довольно удивлен, увидев работу отлично (упрощенную для демонстрационных целей, но вы видите такой код во многих реализациях as_slice()):
extern crate core;
extern crate collections;
use self::collections::str::raw::from_utf8;
use self::core::raw::Slice;
use std::mem::transmute;
fn main() {
let val = "Hello World";
{
let value:&str;
{
let bytes = val.as_bytes();
let mut slice = Slice { data: &bytes[0] as *const u8, len: bytes.len() };
unsafe {
let array:&[u8] = transmute(slice);
value = from_utf8(array);
}
// slice.len = 0;
}
println!("{}", value);
}
}
Так.
Сначала я думал, что это неверный код.
То есть экземпляр Slice
созданный внутри области блока, возвращается вне области блока (путем трансмутации), и хотя код работает, println!
фактически получает доступ к данным, которые более недействительны с помощью небезопасных указателей. Плохо!
... но это, похоже, не так.
Рассмотрим комментирование строки //slice.len = 0;
Этот код все еще работает нормально (печатает "Hello World"), когда это происходит.
Итак, линия...
value = from_utf8(array);
Если это был недопустимый указатель на переменную "slice", значение len
в выражении println()
было бы 0, но это не так. Настолько эффективно копия не только значения указателя, но и полная копия структуры Slice
.
Это правильно?
Означает ли это, что в целом допустимо вернуть a &[T]
до тех пор, пока действительный внутренний указатель данных действителен, независимо от объема оригинала &[T]
, который возвращается, поскольку назначение &[T]
операция копирования?
(Мне кажется, что это чрезвычайно противоречиво интуитивно... поэтому, возможно, я недопонимаю, если я прав, если два &[T]
, указывающие на одни и те же данные, не могут быть действительными, потому что они не будут синхронизировать длины если вы измените один...)