Что означает статический тип Dart и почему он отличается от типа времени выполнения?
В дартс существует два вида типов.
- Тип времени выполнения
- Статический тип
Вот подтверждение в спецификации языка дартс:
Статический тип NULL является снизу.
- Тип выполнения
null
являетсяNull
- Статический тип
null
являетсяbottom
Это означает, что объекты в Dart могут иметь два типа типов.
Один реальный тип, который называется static
и один virtual
тип, который называется runtime
,
То есть тип времени выполнения null
это не bottom
но обычный класс Null
,
class Null {
factory Null._uninstantiable() {
throw new UnsupportedError('class Null cannot be instantiated');
}
/** Returns the string `"null"`. */
String toString() => "null";
}
Но в то же время значение с этим обычным типом времени выполнения Null
может быть назначен любому другому типу, потому что реальный (статический) тип null
это bottom
тип.
Как называется эта техника в дартс?
Замена типа или что-то другое?
PS
Этот вопрос о статических типах значений, но не о статических типах переменных, объявленных с аннотациями типов.
Это потому что null
это не переменная, а value
с static type
из bottom
,
PS
Очень любопытный случай (по крайней мере для меня).
void main() {
Null _null;
String s = _null;
}
Я получаю предупреждение:
A value of type 'Null' cannot be assigned to a variable of type 'String'
Это совершенно правильно. Но в то же время это работает.
Любопытная вещь с подстановкой типов (статическая и во время выполнения).
2 ответа
Тип времени выполнения значения Dart - это его класс. Статический тип выражения Dart - это то, чем его выводит статический тип, и он принадлежит миру статических типов. Этот мир больше, чем просто классы, объявленные в программе. Тип "bottom", тип "dynamic" и тип функции "int->int" являются примерами статических типов, которые не соответствуют классу.
Или другими словами: у значений есть классы, у выражений есть типы (как и во многих других языках). Не существует "статического типа значений", потому что статические типы существуют во время компиляции, а значения существуют только во время выполнения [1].
Алгоритм вывода статического типа указан в спецификации языка Dart. Это то, что есть, и все, что от него требуется, - это то, что он в некотором роде совместим с поведением программы во время выполнения.
Система статических типов - это анализ программ, который пытается обнаружить вероятные ошибки программирования, не более и не менее. Если у вас предупреждение о статическом типе, считается вероятным, но не уверенным, что у вас есть ошибка. Система вывода типов должна выдавать несколько ложных предупреждений и не обнаруживать фактических ошибок, а также быть достаточно простой для описания, понимания и реализации.
Выбор "низа" в качестве типа "ноль" - это просто способ заставить статическую систему типов соответствовать "присваиваемым" отношениям между типами, то есть то, что присваивания проверяются во время выполнения, без необходимости явно проверять "Нуль" везде. Это просто алгоритм, который дает полезный результат.
Статический тип не существует во время выполнения. Например, виртуальная машина не содержит никакой реализации статической системы типов.
/ L
[1] Ну, за исключением константных выражений во время компиляции.
Когда вы объявляете класс и пишете аннотации типов, это статические типы. Поскольку аннотации типов не используются во время выполнения, вы можете назначить значение типа Foo
к переменной типа Bar
, Даже если статический тип Foo
тип времени выполнения Bar
,
Может быть неправильно. Я еще не внимательно изучил эти вопросы.