LINUX.ORG.RU

История изменений

Исправление Siborgium, (текущая версия) :

Речь о части одной глобальной проблемы с move в расте. Код по ссылке прячет реализацию в hashbrown::hash_map as base;, никакой реализации реально там не приведено.

В расте move осуществляется всегда. Я не могу написать код вида

let v: V = ...;
let k: K = ...;
let inserted = map.insert(&k, v);
if !inserted {
    foo(v);
}

потому что владение v безусловно передается в insert. Расту приходится обходить это повсеместно, возвращая v обратно в случае неудачи. Это, мягко говоря, субоптимальное решение. Решения этой проблемы без unsafe не существует – это ограничение базовой модели.

Нельзя осуществлять доступ к глобальным переменным без unsafe. Это ограничение бывает оправдано, но никакого анализа не осуществляется, и абсолютно безопасные случаи оказываются заблокированными. Либо программист анализирует свой код сам и расставляет unsafe там, где он уверен, что все будет в порядке, либо… Заворачивает все в написанные поверх unsafe чьи-то обертки.

И так далее, и так далее. Rc, кстати, нельзя написать без unsafe.

struct Rc<T> { 
    t: T, 
    c: u32, 
} 

impl<T> Clone for Rc<T> {
    fn clone(r: &Self) { 
        // r иммутабельный, не могу увеличить счетчик ссылок 
    } 
} 

Хотя @vertexua, конечно, прав – сделать плохо там сильно сложнее, особенно программисту, мало знакомому с низкоуровневыми языками. Сделать хорошо, впрочем, тоже.

Исходная версия Siborgium, :

Речь о части одной глобальной проблемы с move в расте. Код по ссылке прячет реализацию в hashbrown::hash_map as base;, никакой реализации реально там не приведено.

В расте move осуществляется всегда. Я не могу написать код вида

let v: V = ...;
let k: K = ...;
let inserted = map.insert(&k, v);
if !inserted {
    foo(v);
}

потому что владение v безусловно передается в insert. Расту приходится обходить это повсеместно, возвращая v обратно в случае неудачи. Это, мягко говоря, субоптимальное решение. Решения этой проблемы без unsafe не существует – это ограничение базовой модели.

Нельзя осуществлять доступ к глобальным переменным без unsafe. Это ограничение бывает оправдано, но никакого анализа не осуществляется, и абсолютно безопасные случаи оказываются заблокированными. Либо программист анализирует свой код сам и расставляет unsafe там, где он уверен, что все будет в порядке, либо… Заворачивает все в написанные поверх unsafe чьи-то обертки.

И так далее, и так далее. Rc, кстати, нельзя написать без unsafe.

struct Rc<T> { 
    t: T, 
    c: u32, 
} 

impl<T> Clone for Rc<T> {
    fn clone(r: &Self) { 
        // r иммутабельный, не могу увеличить счетчик ссылок 
    } 
}