Як я можу змінити змінну у Scala?


Відповіді:


282

Кращим методом є використання відповідності шаблонів. Це дозволяє витончено обробити випадок, коли значення, про яке йдеться, не має заданого типу:

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

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

Коротше кажучи, це дійсно шлях. Це трохи синтаксичніше ніж asInstanceOf, але додаткова гнучкість майже завжди того варта.


19
+1, тому що це цікаво, але трохи забагато для цього сценарію. чи не так?
Євген Йокота

що робити, якщо я вже збігався з малюнком, але втратив посилання на закинуте значення: <code> базова відповідність {case MyConcrete (значення) => base.asInstanceOf [MyConcrete]. щось (значення)} </code>, чи є спосіб отримати ' base ', що передається в MyConcrete, навіть якщо ви хочете отримати "значення", використовуючи виклик "непримітити", виконаний "case MyConcrete (значення)"?
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, але необхідний склад. Версія, що відповідає шаблону, ймовірно, є більш багатослівною, ніж гарантованою. Пам’ятайте: Покірно уникайте обманювальної гіпервербосності та безсилля!
hohonuuli

7
@hohonuuli Я думаю, що в цьому конкретному випадку акторський склад прекрасний, але якщо ви використовуєте scala-swingкомпоненти, параметр paintComponent вже є Graphics2D, тому не потрібен
жодний ролик

2
Чому так довго? Чому "asInstanceOf when може бути лише ключовим словом чи методом" as "або" asof "? Або чому вони не просто прийняли спосіб C ++ та Java як варіант, тому що це звичайне і з цим немає великих проблем?
LEMUEL АДАНЕ

16
@LemuelAdane Той факт, що ви взагалі використовуєте касти, є кодовим запахом, не має сенсу робити їх простішими.
Daenyth
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.