Вы правы, думая, что каким-то образом должен быть механизм, который позволит вам избежать каста. Такое приведение будет уродливым и избыточным, так как оно все равно появляется в фильтре. find
, однако, совершенно не заботится о форме предиката, который он получает; он просто применяет его и возвращает Option[A]
, если A
является статическим типом элементов коллекции.
Вам нужна функция collect
:
val boss = People.all.collect { case boss: Authority => boss }.head
collect
создает новую коллекцию. Если вы хотите избежать этого (если вы действительно интересуетесь только первым элементом, который имеет вид Authority
) в случае потенциально очень длинного списка потенциальных боссов, вы можете переключиться на view
, чтобы иметь это лениво оценили:
val boss = People.all.view.collect { case boss: Authority => boss }.head
Наконец, если вы не уверены, что в вашем списке всегда есть хотя бы один начальник, вам следует проверить, был ли поиск успешным, например, как это:
val bossOpt = People.all.view.collect { case boss: Authority => boss }.headOption
bossOpt.foreach(_.giveOrder) // happens only if a boss was found
Редактировать: Наконец, если вы используете Scala 2.9, вам определенно следует использовать collectFirst
, как объяснено в Ответ Кевина Райта .