#flutter #dart #casting
Вопрос:
Мне нужно использовать обратный вызов, который имеет два класса — базовый и производный класс. Мне нужно передать этот тип аргумента в качестве аргумента для обратного вызова, я пытался использовать базовый класс в качестве типа аргумента в typedef, но я получаю следующую ошибку:
The argument type 'bool Function(EmployeeDetails)' can't be assigned to the parameter type 'bool Function(SalesDetails)?'.dart(argument_type_not_assignable).
Я попытался ввести следующую типизацию, которая решает проблему:
Но мне нужен способ предоставить любой из классов в качестве аргумента вместо одного базового класса.
Кроме того, я попытался использовать динамический тип в качестве аргумента в typedef, но он все равно не может быть разрешен и показывает следующую ошибку:
The argument type 'bool Function(SalesDetails)' can't be assigned to the parameter type 'bool Function(dynamic)?'.dart(argument_type_not_assignable)
Вот мой завершенный код:
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Employee emp = Employee((SalesDetails sales) {
EmployeeDetails emp = sales as EmployeeDetails;
return true;
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: Text(
func(emp),
)),
);
}
}
String func(Employee sales) {
String str = 'value';
return str;
}
typedef EmployeeCallback = bool Function(dynamic details);
class Employee {
Employee(this.onValue);
EmployeeCallback? onValue;
}
class SalesDetails {
SalesDetails(this.name, this.id);
final String name;
final num id;
}
class EmployeeDetails extends SalesDetails {
EmployeeDetails(this.empid, String name, num id) : super(name, id);
final num empid;
}
Мне нужно передать любой класс в качестве типа аргумента, как указано ниже:
Ответ №1:
Ваша ошибка в основном заключается в том, что вы говорите: «вы предоставили bool Function(EmployeeDetails)
, но вам нужно было предоставить bool Function(SalesDetails)?
«.
Поскольку это вопрос ООП, давайте использовать животных:
class Animal {
void eat() => print('eating');
}
class Dog extends Animal {
void bark() => print('barking');
}
Используя эти классы, ваша ошибка выглядит так: «вы предоставили bool Function(Dog)
, но вам нужно было предоставить bool Function(Animal)?
«.
Это имеет смысл: параметр ожидает функцию , которая может обрабатывать любую Animal
, но вы дали ей функцию, которая знает только, как обрабатывать Dog
s, например:
void feedAnimals(bool Function(Animal) shouldFeed) {
allAnimals // a List<Animal> from somewhere else in our code
.where(shouldFeed)
.forEach((animal) => animal.feed());
}
Представьте, что вместо этого вы попытались передать а bool Function(Dog)
в это:
final void Function(Dog) shouldFeedDog = (dog) => dog.tailLength > 10;
feedAnimals(shouldFeedDog); // compile error
Если бы этот код не выдавал ошибку во время компиляции, вы бы попытались вызвать .tailLength
все элементы allAnimals
, но не у всех Animal
элементов есть хвосты, поэтому этот код небезопасен.
Чтобы исправить вашу ошибку, вы можете определить bool Function(SalesDetails)
, что делает то, что вы ожидаете:
final bool Function(SalesDetails) checkSalesDetails = (details) {
// perform checking logic
};
// or
bool checkSalesDetails(SalesDetails details) {
// perform checking logic
}
Or, you can change the place you provide the function to be happy with a `bool Function(EmployeeDetails)`. In the animal analogy, this might look like:
```dart
void feedDogs(bool Function(Dog) shouldFeedDog) {
allAnimals
.whereType<Dog>() // filter out non-Dogs, return an Iterable<Dog>
.where(shouldFeedDog)
.forEach((dog) => dog.feed());
}
Комментарии:
1. Использование классов, как показано выше, по-прежнему приводит к следующей ошибке: тип аргумента «Функция bool(данные о сотрудниках)» не может быть присвоен типу параметра » Функция bool(данные о продажах)?». Я изменил typedef следующим образом, используя тип базового класса .
typedef EmployeeCallback = bool Function(SalesDetails details);