
Блогер пропонує іменовані та необов'язкові аргументи для Rust
Автор блогу botahamec.dev вважає відсутність іменованих і необов'язкових аргументів найслабшим місцем Rust. У дописі він порівнює Dart, C# і TypeScript та пропонує власний pre-RFC.
У дописі на botahamec.dev автор стверджує, що найприкріша прогалина в Rust — відсутність іменованих і необов'язкових аргументів. Серед мов, які він «терпить», іменовані аргументи найважче отримати саме в Rust; текст завершується його власним pre-RFC.
Як це роблять інші мови
Dart, створений для графічних інтерфейсів, де компоненти мають багато необов'язкових параметрів, обгортає іменовані параметри у фігурні дужки й дозволяє значення за замовчуванням та модифікатор `required` — автор називає це найкращим рішенням серед розглянутих мов. У C# будь-який параметр можна назвати або дати йому значення за замовчуванням, якщо ці значення стоять після обов'язкових. У TypeScript необов'язкові позиційні параметри працюють добре, але іменовані вимагають деструктурування одного анонімного об'єкта, тож назви полів доводиться писати двічі — автор вважає це зайвою багатослівністю.
Чого ця прогалина коштує Rust
Звичний обхідний шлях у Rust — окрема структура параметрів із реалізацією `Default` і завершенням виклику через `..Default::default()`. На думку автора, це гірше за версію TypeScript: типи не анонімні, значення за замовчуванням, відмінні від типових, вимагають окремої функції, а прийом працює лише тоді, коли значення за замовчуванням має кожен параметр.
Для трьох необов'язкових параметрів `HashMap` зі стандартної бібліотеки має вісім конструкторів, серед них `new`, `with_capacity` і `with_hasher` з варіантами `_in`, і кількість функцій зростає експоненційно. Переплутати порядок теж легко: у `fn print(text: &str, bold: bool, italics: bool, underline: bool)` плутанина другого й третього аргументів непомітно робить текст жирним замість курсиву.
Пропозиція автора
Його pre-RFC робить іменування добровільним за допомогою ключового слова `pub` перед назвою параметра: `fn print_labeled_measurement(pub value: i32, pub unit_label: char = 'm')`, тож виклик може мати вигляд `print_labeled_measurement(value: 5)`. Іменовані аргументи йдуть після позиційних, але між собою їх можна переставляти, і вони можуть мати значення за замовчуванням. Трейти можуть використовувати іменовані параметри, реалізації мусять повторювати назви, а вказівники на функції та трейти `Fn` лишаються позиційними.
Інші варіанти та відкриті питання
Автор також розглядає пропозиції, які вважає гіршими: значення за замовчуванням для полів структур (уже в Nightly Rust, до того ж він написав поліфіл-бібліотеку `feluments`), структурні записи, визнані командою мови надто складними, довгий pre-RFC з Rust Internals Forum, що пропонував перевантаження замість значень за замовчуванням, синтаксис із крапкою на початку та копіювання підходу C#. Оскільки назви необов'язкові, безпека лишається питанням дисципліни: пропонуються лінт Clippy або обов'язкові назви в майбутньому виданні. Відкритими лишаються порядок аргументів, вибір ключового слова `pub` і те, чи завжди значення за замовчуванням мають бути `const`.
SiTech — веброзробка з підтримкою AI
Створюємо швидкі та сучасні сайти й інтегруємо AI у бізнес-процеси. Маєте проєкт чи запитання? Із задоволенням допоможемо.