Вы могли реализовать его как это:
@SuppressWarnings("unchecked")
public T callFriend(String name) {
return (T)friends.get(name);
}
(Да, это - свод законов; см. Дженерики Java: Универсальный тип определяется как тип возврата [только 116].)
тип возврата будет выведен от вызывающей стороны. Однако отметьте @SuppressWarnings
аннотация: это говорит Вам, что этот код не безопасен с точки зрения типов . Необходимо проверить его сами, или Вы могли добраться ClassCastExceptions
во времени выполнения.
, К сожалению, способ, которым Вы используете его (не присваивая возвращаемое значение временной переменной), единственный способ сделать компилятор счастливым, состоит в том, чтобы назвать его как это:
jerry.callFriend("spike").bark();
, В то время как это может быть немного более хорошо, чем кастинг, Вы - вероятно, более обеспеченное предоставление Animal
, классифицируют метод краткого обзора talk()
, как сказал David Schmitt.
Вы также можете сделать что-то вроде
type 'a RecType = RecType of ('a -> 'a RecType)
, чтобы создать именованный тип, через который будет выполняться рекурсия. Теперь это работает:
let rec specialF = RecType (fun _ -> specialF)
type d<'T> = delegate of 'T -> d<'T> //'
let del : d<int> = null
let anotherDel = del.Invoke(1).Invoke(2).Invoke(3)
Я думаю, вам нужен именованный тип, который может быть представлен непосредственно в интерфейсе командной строки для прерывания рекурсии, поэтому в F # это означает, что вам также нужен фактический тип делегата.
Рекурсивные типы записей тоже должны работать.
type A = { A : A }
let rec a : A = { A = a }
Мне было бы интересно найти практическое применение. Или даже непрактичный :)