先说下我的理解,如果有误感谢大佬们指出:
- 
[T; N]类似于数组的概念,长度在编译期可知,且不会变化,长度N也是类型的一部分。[T; N]满足Sized trait 
- 
[T]和[T; N]的区别在于[T]的长度在编译期不可知,不满足Sized trait。因此一般都使用&[T]来指向[T],这个指针除了有数据的地址,还保存有[T]的长度信息,因此被称为胖指针fat pointer 
现在有这样一段代码
fn main() {
    let array: [u8; 5] = [1, 2, 3, 4, 5];
    let slice: &[u8] = &array[..];
    println!("Array pointer size {}", size_of_val(&&array));  // 8
    println!("Slice pointer size {}", size_of_val(&slice));   // 16
    println!("Array length {}", array.len());                 // 5
    println!("Slice length {}", slice.len());                 // 5
}
Array的指针大小是8 bytes,Slice则是16 bytes,似乎正好满足Slice是fat pointer的事实。
接下来问题来了,发现array.len()和slice.len()都调用的是下面的代码
impl<T> [T] {
    pub const fn len(&self) -> usize {
        ptr::metadata(self)
    }
}
array和slice都是从自己的指针中取metadata,那么两个都是胖指针?那为什么打印Array指针大小为8而不是16呢?
还是说我计算Array指针大小的写法是错误的?
求大佬们解答一下,谢谢~
	    
	    
		1
	    
	    
	    共 3 条评论, 1 页
	
	
    
评论区
写评论感谢感谢😀,没人教的话我怎么也不会想到是这个原因
--
👇
aj3n: https://doc.rust-lang.org/stable/reference/type-coercions.html#unsized-coercions
你关于指针长度的理解没有问题. 两种写法都调用的<[T]>::len主要是因为调用array.len()的时候发生了
unsized-coercion, 会把&[T;N]隐式转换成&[T], 参考上面的链接; 我感觉这个不是很重要标准库实现技巧,以后对关注到类似的隐式转换简单参考下就好;个人理解
array是相当于下面一个C语言结构体数据&array相当于下面一个C语言结构体数据:&&array相当于下面一个C语言ArrayRef的指针:&&array=&ArrayRef所以
size_of_val(&&array)是返回当前平台存储的指针大小,size_of_val(&array)返回ArrayRef结构体大小https://doc.rust-lang.org/stable/reference/type-coercions.html#unsized-coercions
你关于指针长度的理解没有问题. 两种写法都调用的<[T]>::len主要是因为调用array.len()的时候发生了
unsized-coercion, 会把&[T;N]隐式转换成&[T], 参考上面的链接; 我感觉这个不是很重要标准库实现技巧,以后对关注到类似的隐式转换简单参考下就好;