What does the box keyword do?
在Rust中,我们可以使用
我很好奇
1 2 3 4 5 6 7 8 9 | impl< T > Box< T > { /// Allocates memory on the heap and then moves `x` into it. /// [...] #[stable(feature ="rust1", since ="1.0.0")] #[inline(always)] pub fn new(x: T) -> Box< T > { box x } } |
实现中的唯一行返回值
答案是标有lang项目
最后,
-
box 结构上的owned_box 封装分配的指针。此结构不需要Drop 实现,它是由编译器自动实现的。 -
exchange_malloc 分配内存。 -
exchange_free 释放先前分配的内存。
使用此
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #![feature(lang_items, box_syntax, start, no_std, libc)] #![no_std] extern crate libc; extern { fn abort() -> !; } #[lang ="owned_box"] pub struct Box< T >(*mut T); #[lang ="exchange_malloc"] unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { let p = libc::malloc(size as libc::size_t) as *mut u8; // malloc failed if p as usize == 0 { abort(); } p } #[lang ="exchange_free"] unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) { libc::free(ptr as *mut libc::c_void) } #[start] fn main(argc: isize, argv: *const *const u8) -> isize { let x = box 1; 0 } #[lang ="stack_exhausted"] extern fn stack_exhausted() {} #[lang ="eh_personality"] extern fn eh_personality() {} #[lang ="panic_fmt"] fn panic_fmt() -> ! { loop {} } |
注意,没有为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | define internal i64 @_ZN4main20hbd13b522fdb5b7d4ebaE(i64, i8**) unnamed_addr #1 { entry-block: %argc = alloca i64 %argv = alloca i8** %x = alloca i32* store i64 %0, i64* %argc, align 8 store i8** %1, i8*** %argv, align 8 %2 = call i8* @_ZN8allocate20hf9df30890c435d76naaE(i64 4, i64 4) %3 = bitcast i8* %2 to i32* store i32 1, i32* %3, align 4 store i32* %3, i32** %x, align 8 call void @"_ZN14Box$LT$i32$GT$9drop.103617h8817b938807fc41eE"(i32** %x) ret i64 0 } |
同时,按预期调用了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | define internal void @"_ZN14Box$LT$i32$GT$9drop.103617h8817b938807fc41eE"(i32**) unnamed_addr #0 { entry-block: %1 = load i32** %0 %2 = ptrtoint i32* %1 to i64 %3 = icmp ne i64 %2, 2097865012304223517 br i1 %3, label %cond, label %next next: ; preds = %cond, %entry- block ret void cond: ; preds = %entry-block %4 = bitcast i32* %1 to i8* call void @_ZN10deallocate20he2bff5e01707ad50VaaE(i8* %4, i64 4, i64 4) br label %next } |
就是这样,在编译器生成的Drop上调用
注意,即使在标准库上,
在
作为进一步参考,您可以阅读RFC,该RFC更改了" placement new"语法,并对其进行了选通。
我相信您找不到
1 2 3 4 | #[lang ="owned_box"] #[stable(feature ="rust1", since ="1.0.0")] #[fundamental] pub struct Box< T >(Unique< T >); |
因为它是一个lang项目,所以编译器具有特殊的逻辑来处理其实例化,可以使用
我相信编译器会将框分配委托给
至于