Тип-подсказки используются, чтобы избежать отражения;они (в настоящее время) не используются для статического ввода аргументов функций или конструкторов (исключение составляют примитивы, поскольку их нельзя отнести к категории Object
).Таким образом, они не делают ничего для простой записи, но имеют значение, когда дело доходит до добавления реализации протокола, например:
user=> (set! *warn-on-reflection* true)
true
user=> (defprotocol P (foo [p]))
P
user=> (defrecord R [s] P (foo [_] (.getBytes s))) ; getBytes is a method on String
Reflection warning, NO_SOURCE_PATH:6 - reference to field getBytes can't be resolved.
user.R
user=> (foo (R. 5))
java.lang.IllegalArgumentException: No matching field found: getBytes for class java.lang.Integer (NO_SOURCE_FILE:0)
user=> (defrecord R [^String s] P (foo [_] (.getBytes s)))
user.R
user=> (foo (R. 5))
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String (NO_SOURCE_FILE:0)
Разница между двумя версиями заключается в том, что последняя испускает вызов байт-кодаString.getBytecode()
(следовательно, ClassCastException при передаче целого числа), тогда как первому необходимо выяснить, что именно означает .getBytes
в отношении объекта времени выполнения, переданного функции (и этот процесс завершается неудачно, когда передается целое число).