LINUX.ORG.RU

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

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

Да, придётся назвать разные функции по разному.

Смысл перегрузки как раз в том, что они названы одинаково и содержатся в оверлоад сете, из которого выбираются в зависимости от полученных аргументов.

который предлагает другие средства для решения таких задач

Нет, он не предлагает никаких средств для решения такой задачи. Раст предлагает использовать трейты, которые хардкодят интерфейс и вынуждают адаптировать код под них.

конструктор с параметрами - это замыкание

Нет конечно. Без исключений нет никакой возможности вернуть ошибку из конструктора, а со статическими функциями вместо конструктора у вас не будет полиморфизма. Точнее, его в принципе не будет без перегрузки, вам придется все сводить к интерфейсам (трейтам). Вы просто предлагаете перенести задачу конструирования валидного T на плечи вызывающего кода, вызываемому же коду придется осуществлять дополнительную проверку на ошибки – она уже была осуществлена в замыкании, либо в теле конструктора. С тем же успехом можно переписать все это дело в

if v.capacity() > v.len() {
    v.push(Bar::new(a));
    // ...
} else {
    // ...
}

Реализуется. Перемещать или нет аргументы конструктора в замыкание решает тот, кто пишет замыкание.

Скажем так, я признаю, что с приседаниями в расте все же можно эмулировать conditional move, но считаю это малоосмысленным. Конструировать просто Bar неинтересно – задача же конструирования произвольного T все еще не решена. Тем более in-place. move по умолчанию это все еще move, пусть и дешевый. Когда в дело включается Pin, все становится еще интереснее.

Перемещать или нет аргументы конструктора в замыкание решает тот, кто пишет замыкание.

Вы привели три варианта, но из них только 1 осуществляет передачу владения куда-то. Кстати, реализовать все сразу я не смогу – Bar::new мономорфен по ссылке, и мне придется использовать, например, Bar::new для move/clone и Bar::from_ref для ссылки.

Дополню про exceptions: в расте очень много где используется Result<T, Box<dyn Error>>. На этом моменте любая выгода Result вместо исключения пропадает, а вот многочисленные проблемы (необходимость раскручивать стек руками, unwrap’ы, «грязный» интерфейс) остаются.

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

Да, придётся назвать разные функции по разному.

Смысл перегрузки как раз в том, что они названы одинаково и содержатся в оверлоад сете, из которого выбираются в зависимости от полученных аргументов.

который предлагает другие средства для решения таких задач

Нет, он не предлагает никаких средств для решения такой задачи. Раст предлагает использовать трейты, которые хардкодят интерфейс и вынуждают адаптировать код под них.

конструктор с параметрами - это замыкание

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

if v.capacity() > v.len() {
    v.push(Bar::new(a));
    // ...
} else {
    // ...
}

Реализуется. Перемещать или нет аргументы конструктора в замыкание решает тот, кто пишет замыкание.

Скажем так, я признаю, что с приседаниями в расте все же можно эмулировать conditional move, но считаю это малоосмысленным. Конструировать просто Bar неинтересно – задача же конструирования произвольного T все еще не решена. Тем более in-place. move по умолчанию это все еще move, пусть и дешевый. Когда в дело включается Pin, все становится еще интереснее.

Перемещать или нет аргументы конструктора в замыкание решает тот, кто пишет замыкание.

Вы привели три варианта, но из них только 1 осуществляет передачу владения куда-то. Кстати, реализовать все сразу я не смогу – Bar::new мономорфен по ссылке, и мне придется использовать, например, Bar::new для move/clone и Bar::from_ref для ссылки.