Я бы сказал, что если вы приведете объект типа String
к Any
, если вы хотите использовать метод, определенный в String
, вы должны привести его обратно к String
.
Вы приводите функцию как функцию, которая принимает аргумент экзистенциального типа (что означает _
в контексте типа), поэтому вы не можете использовать ее как функцию, которая принимает Int
. Чтобы использовать его как функцию, которая берет Int
, вы должны привести ее обратно.
Та же проблема существует при сопоставлении шаблонов с коллекциями или другими общими классами:
def firstLength(collection: Any): Int ={
collection match {
// this is how you would have liked to write it
// case list: List[String] => list.head.length
// case map: Map[String, String] => map.values.head.length
// but this is how you have to write it because of type erasure
case list: List[_] => list.asInstanceOf[List[String]].head.length
case map: Map[_, _] => map.asInstanceOf[Map[String, String]].values.head.length
}
}
Информация о типе отсутствует, поэтому вы не можете сопоставить ее с List[String]
, вместо этого вы должны сопоставить экзистенциальный тип List[_]
(возможно, вы ошиблись в том, как вы это говорите, это не общий тип экзистенциально, я думаю) а потом снимали. Это более или менее точно ваша проблема, тип, который вы стерли после, и нет никакого способа вернуть его (если вы не можете использовать тот же трюк с ClassManifest
, который можно использовать, чтобы обойти стирание типа в случаях, подобных приведенному выше [но на самом деле это не так, как описано выше, потому что это немного небрежно]).