#flutter
#flutter
Вопрос:
class Foo extends StatelessWidget {
Widget _buildBar() => Bar();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: Bar(), // Compile-time error
appBar: _buildBar(), // Works
);
}
}
class Bar extends StatelessWidget {
@override
Widget build(BuildContext context) => AppBar();
}
Когда я присваиваю Bar()
значение appBar
, это выдает ошибку времени компиляции, но когда я присваиваю _buildBar()
, это просто работает. В обоих случаях, Bar()
и _buildBar()
, я возвращаю обычный, Widget
а не PreferredSizeWidget
.
Ответ №1:
Это потому, что AppBar должен реализовывать PreferredSizeWidget, что означает, что он должен знать свой собственный размер перед процессом сборки.
Когда вы используете Bar () напрямую, виджет не может узнать свой собственный размер перед запуском сборки. Когда вы вызываете функцию, которая возвращает Bar(), ее собственная сборка уже запущена, и виджет знает свой собственный размер.
Комментарии:
1. Я уже знал о первом абзаце. Переходя ко второму, я не запускаю приложение, это просто ошибка времени компиляции,
build()
метод ничего не знает о том, что делают другие методы. Это ошибка, отображаемая компилятором, а не самой виртуальной машиной.2. Анализатор Dart может определить, что выходит из функции, и поскольку он вернет виджет с известным размером (после метода внутренней сборки), он проходит. При использовании самого виджета анализатор делает вывод, что его размер будет известен только после запуска внутренней сборки, но это произойдет только одновременно с методом внешней сборки, выдавая ошибку. Двумя ключами здесь являются Dart analyzer и функция, которые должны быть завершены перед возвратом.
3. Говоря о части метода, Dart analyzer знает, что метод возвращает
Widget
(это показано как в типе возвращаемого метода, так и в теле), и анализатор также знает, чтоappBar
может быть присвоен толькоPreferredSizeWidget
, а не обычныйWidget
. Итак, при назначении методаappBar
должна возникать ошибка времени компиляции.4. dart.dev/guides/language/type-system#что такое надежность Анализатор Dart многое может сделать без компиляции. Главное — это внутренние и внешние методы построения дерева виджетов. Функция всегда будет принудительно запускать внутреннюю сборку перед возвратом. Непосредственно инкапсулированный виджет будет запускать свою собственную сборку одновременно со своей родительской сборкой.
5. Я попробую немного кода на Dartpad и вернусь для дальнейшего обсуждения.