рекордов на уровне "named-tuple без какого-либо coerce'а", и вот думаю, а какие проблемы могут быть с ним?
К примеру, мы можем сделать impl Trait for {a: i32}, также как и impl Trait for (i32,), но, понятно, что struct Struct {a: i32} не должна как-либо коерситься в {a: i32}, при этом, я вижу очевидные кейсы, где такое было бы удобно. И вот вопрос в том, когда удобство начинает всё ломать.
К примеру
struct S {
field: i32,
}
fn foo(a: S) {}
a({field: 123})
Может быть очень даже удобно, но я могу сказать, что {field: i32} может не имплементировать то же, что и S, следовательно такой pass в функцию не может быть выполнен, ведь в функции мы делаем проверки, основываясь на том, что a: S, а не a: {field: i32}.
Инвертированный пример это:
struct S {
field: i32,
}
fn foo(a: {field: i32}) {}
a(S {field: 123})
И тут можно сказать абсолютно то же самое, ведь {field: i32} это такой же distinct тип, как и S, следовательно у него может быть свой набор методов, которым S может не удовлетворять. Да и вообще любые "может" надо откидывать, ведь иначе начнется duck-typing, либо SFINAE.
И в итоге, мне интересно, какой максимальный профит можно выжать из рекордов, в контексте взаимодействия с номинальными типами, при это не уходя во мрак. Я уверен, что даже если и найду какие-то компромиссы, то пропущу подводные камни, связанные со системой типов напрямую или же с правилами разрешения реализаций (trait/impl).
На данный момент я не вижу проблем с тем, чтобы иметь рекорды в виде абсолютно отдельного типа, как tuple'ы, но и тут я могу чего-то не замечать.
тупые DTO
Обсуждают сегодня