Рефакторинг в Rust проще, чем кажется. Если вы пройдете компилятор, скорее всего, вы все сделали правильно.

Рефакторинг в Rust намного медленнее, чем в других языках, потому что одна из частей рефакторинга заключается в разделении кода на функции, а функции требуют подписи. Которые не очевидны.

Смотреть:

старый код:

let mut buf = im::ImageBuffer::from_fn(
    x, y, |_, __| {
          im::Rgba([255,255,255,255]) 
    }
);

Теперь я хочу изменить буфер на свою собственную структуру. Я хочу использовать несколько буферов вместо одного. Первый шаг — создать свой собственный тип Buffer:

struct Buffer{
    buf: im::ImageBuffer
}

Ha. Ha ha. Ha ha ha.

Нет, есть множество параметров типа, которые вам нужно заполнить. Вам не нужно было заполнять их раньше из-за наследования типов, но все функции требуют полных подписей, и ваш новый тип должен либо погрузиться в дженерики, либо закрепить эти типы.

Это правильное объявление типа:

struct Buffer{
    buf: im::ImageBuffer<im::Rgba<u8>,Vec<u8>>
}

Теперь нам нужно написать «новую» функцию. Я хочу сделать его простым в использовании:

impl Buffer{
    fn new(x:u32, y:u32)-> Self{
        Buffer{
            buf: im::ImageBuffer::from_fn(
               x, y,
               |_, __| {
                 im::Rgba([255,255,255,255]) 
               }
            )
        }
    }
}

И заменить нашу первую строку исходного кода.

Вы подозреваете, что я прыгаю на фургоне нового типа:

let mut buf = Buffer::new(x, y);

Но нет. Вот мой первый микротрюк для нормального рефакторинга.

let mut buffer = Buffer::new(x, y);
let mut buf = buffer.buf;

Выглядеть глупо, да? Но я уже могу его скомпилировать. Все другие варианты использования buf не затрагиваются, и я могу включить их для буферизации по одному вместо подхода «все или ничего» для переключения типов. Постепенные изменения допускают постепенные неудачи, что намного лучше, чем полное поражение, если что-то не согласуется с другими частями (что, к сожалению, иногда случается при моем рефакторинге Rust).

Следующий шаг — заменить все buf на buffer.buf, и вы (я) можете выбросить let mut buf = buffer.buf; строку.

Итак, идея состоит в том, чтобы медленно сканировать новый тип один за другим, «извлекая» содержимое нового типа (это старый тип, который мы рефакторим).