Неявная проверка названий аргументов
От: vsb Казахстан  
Дата: 06.08.20 11:48
Оценка:
Не первый раз сталкиваюсь с, возможно, странной хотелкой... Суть такова. Имеется метод с определёнными параметрами. У параметров есть название. К примеру

void processPerson(String id, String lastName);


При вызове метода в scope имеются переменные, среди которых переменные с соответствующими названиями, которые чаще всего и нужно передавать аргументами.

String id, lastName, firstName, ...;
...

processPerson(id, lastName);


Собственно этот юз-кейс повторяется достаточно часто. При этом IDE достаточно умна, чтобы даже подсказывать весь список аргументов в такой ситуации. Но, конечно же, если я напишу processPerson(firstName, lastName) никто меня не остановит. Может быть в какой-то ситуации это даже и нужно, но скорей всего это будет ошибка.

Как вы думаете, можно ли отлавливать такую ошибку в современных языках программирования? Желательно пораньше. А то в этом случае её отловить можно только сильно пост-фактум, например когда в базу сядут неправильные данные и через год их кто-то захочет проанализировать.

Смешно, но ближе всего к тому, что я хочу, находится современный JavaScript, если писать в стиле

function processPerson({id, lastname}) {
    
}
...
let id, lastName, firstName;
...
processPerson({id, lastName}); // id = id, lastName = lastName
processPerson({id, lastName: firstName}); // id = id, lastName = firstName


Тут, конечно, статической проверки типов во время компиляции нет, но хотя бы во время выполнения есть шанс поймать ошибку пораньше.

Возможно в TypeScript это можно и на этапе компиляции отловить, не знаю...

Правда я не уверен, что на JavaScript в реальности так пишут, но по крайней мере могут писать. Причём у того, кто вызывает функцию, нет возможности отвертеться от указания имён.

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

fun main() {
    val id = ""
    val lastName = ""
    val firstName = ""
    processPerson(id = id, lastName = lastName)
}

fun processPerson(id: String, lastName: String) {
}


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

В общем резюмирую: хотелось бы функции с навязанно-именованными параметрами (т.е. которые нельзя вызвать без перечисления имён параметров) и с коротким синтаксисом для случая, когда имя параметра и имя идентификатора-аргумента совпадают. Что-то вроде processPerson(=id, lastName = firstName).

Есть ли такое где-либо? Или может какой-нибудь паттерн есть, кроме вкорячивания классов-хранилищ с билдерами на каждый чих.
Отредактировано 06.08.2020 11:54 vsb . Предыдущая версия . Еще …
Отредактировано 06.08.2020 11:52 vsb . Предыдущая версия .
Отредактировано 06.08.2020 11:52 vsb . Предыдущая версия .
Отредактировано 06.08.2020 11:51 vsb . Предыдущая версия .
Отредактировано 06.08.2020 11:50 vsb . Предыдущая версия .
Отредактировано 06.08.2020 11:49 vsb . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.