Как я могу привести переменную в Scala?

199

Учитывая переменную с типом Graphics, как я могу привести ее Graphics2Dв Scala?

Евгений Йокота
источник

Ответы:

282

Предпочтительным методом является использование сопоставления с образцом. Это позволяет изящно обрабатывать случай, когда рассматриваемое значение не относится к данному типу:

g match {
  case g2: Graphics2D => g2
  case _ => throw new ClassCastException
}

Этот блок копирует семантику asInstanceOf[Graphics2D]метода, но с большей гибкостью. Например, вы можете предоставить разные ветви для разных типов, эффективно выполняя несколько условных приведений одновременно. И, наконец, вы не на самом деле нужны , чтобы бросить исключение в броской всей области, вы могли бы также вернуться null(или , предпочтительно, None), или вы могли бы ввести некоторую резервную ветвь , которая работает без Graphics2D.

Короче говоря, это действительно путь. Это немного более синтаксически громоздко asInstanceOf, но дополнительная гибкость почти всегда стоит того.

Даниэль Спивак
источник
19
+1, потому что это интересно, но слишком много для этого сценария. не так ли?
Юджин Йокота
Что, если я уже сопоставил с образцом, но потерял ссылку на приведенное значение: <code> base match {case MyConcrete (value) => base.asInstanceOf [MyConcrete] .something (value)} </ code>, есть ли способ получить ' base 'приведен к MyConcrete, даже если вы хотите извлечь "значение", используя вызов "unapply", выполняемый "case MyConcrete (value)"?
ithkuil
4
Попробуйте это: base match { case base @ MyConcrete(value) => base.something(value) } Очевидно, теневое копирование baseнеобязательно. Вы также можете легко использовать другое имя переменной.
Даниэль Спивак
Чего я не понимаю, так как вы бы получили результат сопоставления с образцом, приведенный к переменной? как в Java, если это было String a = (String) b; каким будет эквивалент скалы?
Джеймс МакМэхон
@JamesMcMahonval gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }
Кевин Мередит
224
g.asInstanceOf[Graphics2D];
Евгений Йокота
источник
36
Как только я привык к Scala, я научился не использовать asInstanceOf, так как это побеждает цель иметь статическую систему типов и кажется отвратительным.
Евгений Йокота
26
К сожалению, это обычная операция при использовании Swing. Для пользовательских операций рисования вам необходимо переопределить метод public void paintComponent (Graphics g). Параметр Graphics на самом деле является экземпляром Graphics2D, но требуется приведение. Версия сопоставления с образцом, вероятно, более многословна, чем обоснованная. Помните: соблазнительно воздерживайтесь от запутывания и гипервозрастности!
Хохонуули
7
@hohonuuli Я думаю, что приведение в порядке в этом конкретном случае, но если вы используете scala-swingкомпоненты, параметром paintComponent уже является Graphics2D, так что приведение не требуется
Luigi Plinge
2
Почему это так долго? Почему «asInstanceOf тогда может быть только как» или «asof» ключевое слово или метод? Или почему они просто не приняли C ++ и Java в качестве опции, потому что это общепринятый вариант и с этим нет большой проблемы?
LEMUEL ADANE
16
@LemuelAdane Тот факт, что вы вообще используете приведение типов, является запахом кода, нет смысла делать их проще.
Daenyth