Является ли функция (int) функцией (объектом) в Dart?

#dart

#dart

Вопрос:

 Function foo = (int x) =&&t; x;

if (foo is Function(Object)) { 
  print('Bar'); // Doesn't print
}
  

По моему мнению, Function(int) это подтип Function(Object) , поскольку type int является подтипом type Object и, следовательно, if условие должно возвращать true , но это не так. Почему это так?

Я не получил никакого хорошего названия для этого вопроса, не стесняйтесь изменить его.

Ответ №1:

Это не так.

Суть подтипов в том, что экземпляр подтипа может использоваться везде, где ожидается экземпляр супертипа (также известный как «взаимозаменяемость»).

Function(Object) Может быть вызвана с любым объектом в качестве аргумента. Она может вызываться как с "foo" , так и 42 в качестве аргументов. Function(int) Не может быть вызвана со строкой в качестве аргумента. Это означает, что a Function(int) не может быть заменено там, где ожидается a Function(Object) , и система типов действительно не создает Function(int) подтипа Function(Object) .

Вместо этого она создает Function(Object) подтип Function(int) , потому что если функция, которая может быть вызвана с любым аргументом, то ее можно использовать везде, где требуется функция, принимающая int аргумент — потому что она принимает int .

В общем случае, R1 Function(P1) тип функции является подтипом R2 Function(P2) , если R1 является подтипом R2 и P2 является подтипом P1 . Обратите внимание на обратный порядок типов параметров. Типы параметров ковариантны.

Подумайте об этом так: функцию можно использовать там, где ей присвоен аргумент типа P и ожидается, что она вернет значение типа R, если (и только если) она принимает любой P аргумент и, возможно, больше, и все значения, которые она может возвращать, должны быть R значениями , но не обязательно всеми R значениями.

То есть тип функции является подтипом, R Function(P) если он принимает минимум P и возвращает максимум R .

Комментарии:

1. Я уверен, что нигде в Интернете не найду лучшего объяснения, чем это. Большое спасибо, Лассе, сэр.

Ответ №2:

Хотя это не сразу интуитивно понятно, подтипирование противоположно: Function(Object) является подтипом Function(int) . Действительно, тип A может быть подтипом B только в том случае, B если все, что имеет значение about A , также имеет значение about,,,. Function(Object) всегда может быть вызвана с int аргументом, но Function(int) не может быть вызвана с произвольным Object , поэтому:

 Function foo = (Object x) =&&t; x;

if (foo is Function(int)) { 
   print('Bar'); // prints!
}
  

Другими словами, функции контравариантны по типу параметра.

Комментарии:

1. Привет, спасибо за ваш ответ. Но Function(int) также может быть вызвана с помощью Object .

2. @iLoveFlutterDocs, который вы не можете вызвать Function(int) , например, с помощью строки, не так ли?

3. Я думаю, вы меня неправильно поняли. Скажем, Object является int ли она Object obj = 1 , тогда вы можете вызвать Function(int) с obj помощью.

4. @iLoveFlutterDocs Ах, я понимаю, что ты имеешь в виду. Система типов Dart кажется немного более расслабленной, поэтому она опускает некоторые статические проверки для вызовов функций. Но это все еще применимо к is оператору. Нужно найти, действительно ли это где-то задокументировано.