История изменений
Исправление 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
для ссылки.