Пример исходного кода:
void main() {
final func = () => petOwners.selectMany(
(petOwner) => petOwner.pets, (petOwner, petName) => {petOwner: petName});
print(func.runtimeType);
}
final petOwners = [
PetOwner('Higa', ['Scruffy', 'Sam']),
PetOwner('Ashkenazi', ['Walker', 'Sugar']),
PetOwner('Price', ['Scratches', 'Diesel']),
PetOwner('Hines', ['Dusty']),
];
class PetOwner {
String name;
List<String> pets;
PetOwner(this.name, this.pets);
}
extension IEnumerable<TSource> on Iterable<TSource> {
Iterable<TResult> selectMany<TCollection, TResult>(
Iterable<TCollection> Function(TSource) collectionSelector,
TResult Function(TSource, TCollection) resultSelector) {
return null;
}
}
Вывод:
() => Iterable<Map<PetOwner, dynamic>>
То есть вместо получения результата () => Iterable<Map<PetOwner, String>>
я получаю довольно странный результат вида () => Iterable<Map<PetOwner, dynamic>>
.
В этом довольно простом случае компилятор Dart не может вывести тип "TCollection".
Я не могу понять, в чем причина. Код довольно прост. Проще некуда.
Тем не менее, результат очень плохой. Это ошибка в компиляторе или это сделано в соответствии со спецификацией языка?
Если это соответствует спецификациям, то почему было принято это решение? Есть ли в этом какие-то преимущества (в такой минимизации и упрощении)?
PS
Тот же самый простой код, написанный на C#, работает без проблем.
РЕДАКТИРОВАТЬ:
Проблема в том, что компилятор не может вывести тип "TCollection" из этого кода (Iterable<TCollection> Function(TSource) collectionSelector
):
(petOwner) => petOwner.pets
Компилятор должен учитывать этот код следующим образом:
() => (PetOwner) => List<String>
Но компилятор распознает этот код следующим образом:
() => (PetOwner) => dynamic