2016-10-21 3 views
9

Эта простая программа:Почему `` Box :: in_raw` не принимает `self` в качестве параметра?

fn main() { 
    let b: Box<i32> = Box::new(1); 
    b.into_raw(); 
} 

Производит эту неудобную ошибку при компиляции с Rust 1.12.0:

error: no method named `into_raw` found for type `Box<i32>` in the current scope 
--> <anon>:3:7 
    | 
3 |  b.into_raw(); 
    |  ^^^^^^^^ 
    | 
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter 
    = note: candidate #1 is defined in an impl for the type `Box<_>` 

Это потому, что into_raw не определен принимать self в качестве параметра, но вместо этого определяется как :

impl Box<T: ?Sized> { 
    fn into_raw(b: Box<T>) -> *mut T; 
} 

Это кажется неудобным, и я не могу найти обоснования.

Итак ... почему?

ответ

9

Потому что 99.995% времени (статистика полностью составлена), you expect method calls to happen to the thing being pointed to, not to the pointer itself. В результате типы «умного указателя» в Rust обычно избегают делать что-либо, чтобы сломать это ожидание. Очевидным исключением будет Rc/Arc, осуществляющий непосредственно Clone.

+0

Ах спасибо! Я полностью разрушал свой мозг в совершенно неправильном направлении и не считал, что большинство вызовов метода направляются к плакату через «Дефер». –

7

Box инвентарь Deref, что означает, что все методы, которые прилагаются Box, автоматически становятся доступными; снаружи, Box<T> и T смотрите и действуйте одинаково.

Если into_raw был методом вместо ассоциированной функции, он затеняет любой метод into_raw на содержащийся тип.

Есть и другие примеры этих усиливающих связанных с ними функций на Rc, такие как downgrade или try_unwrap, или на Arc, такие как make_mut.

+2

См. [Запрос на извлечение] (https://github.com/rust-lang/rust/pull/21318), добавив эти функции в стандартную библиотеку. – thirtythreeforty

+0

@thirtythreeforty: Отличный источник, действительно, комментарий alexcrichton точно объясняет это. –

Смежные вопросы