Bagaimana cara saya membuat variabel di Scala?

199

Diberikan variabel dengan tipe Graphics, bagaimana cara saya melemparkannya ke Graphics2Ddalam Scala?

Eugene Yokota
sumber

Jawaban:

282

Teknik yang disukai adalah menggunakan pencocokan pola. Ini memungkinkan Anda menangani kasus dengan anggun bahwa nilai yang dimaksud bukan dari jenis yang diberikan:

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

Blok ini mereplikasi semantik dari asInstanceOf[Graphics2D]metode ini, tetapi dengan fleksibilitas yang lebih besar. Misalnya, Anda dapat memberikan cabang yang berbeda untuk berbagai jenis, secara efektif melakukan gips bersyarat pada saat yang sama. Akhirnya, Anda tidak benar - benar perlu melemparkan pengecualian di area tangkap semua, Anda juga bisa kembali null(atau lebih disukai, None), atau Anda bisa memasukkan beberapa cabang mundur yang bekerja tanpa Graphics2D.

Singkatnya, ini benar-benar cara untuk pergi. Ini sedikit lebih sintaksis daripada asInstanceOf, tetapi fleksibilitas tambahan hampir selalu sepadan.

Daniel Spiewak
sumber
19
Memberi +1 karena menarik, tetapi terlalu banyak untuk skenario ini. bukan?
Eugene Yokota
bagaimana jika saya sudah mencocokkan pola tetapi kehilangan referensi ke nilai yang dicor: <c> base match {case MyConcrete (value) => base.asInstanceOf [MyConcrete] .sesuatu (nilai)} </code>, apakah ada cara untuk mendapatkan ' base 'dicor ke MyConcrete bahkan jika ingin mengekstraksi "value" dengan mengeksploitasi panggilan' unapply 'yang dilakukan oleh "case MyConcrete (value)"?
ithkuil
4
Coba ini: base match { case base @ MyConcrete(value) => base.something(value) } Jelas, membayang baseadalah opsional. Anda bisa dengan mudah menggunakan nama variabel yang berbeda.
Daniel Spiewak
Yang tidak saya dapatkan adalah bagaimana Anda mendapatkan hasil dari pencocokan pola ini ke dalam variabel? seperti di java jika itu adalah String a = (String) b; apa yang akan setara dengan scala?
James McMahon
@JamesMcMahonval gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }
Kevin Meredith
224
g.asInstanceOf[Graphics2D];
Eugene Yokota
sumber
36
Setelah saya terbiasa dengan Scala, saya belajar untuk tidak menggunakan asInstanceOf, karena itu mengalahkan tujuan memiliki sistem tipe statis dan terasa menjijikkan.
Eugene Yokota
26
Sayangnya, ini adalah operasi yang umum saat menggunakan Swing. Untuk operasi pengecatan khusus, Anda perlu mengganti metode 'public void paintComponent (Graphics g)'. Parameter Graphics sebenarnya adalah instance Graphics2D, tetapi dibutuhkan pemain. Versi pencocokan pola mungkin lebih verbositas daripada yang dibenarkan. Ingat: Hindari hiperverbositas dan proklikitas yang membingungkan!
hohonuuli
7
@hohonuuli Saya pikir para pemain baik-baik saja dalam kasus khusus itu, tetapi jika Anda menggunakan scala-swingkomponen, parameter paintComponent sudah Graphics2D jadi tidak diperlukan pemeran
Luigi Plinge
2
Kenapa begitu lama? Mengapa "asInstanceOf ketika hanya dapat" sebagai "atau" asof "kata kunci atau metode? Atau mengapa mereka tidak hanya mengadopsi cara C ++ dan Java sebagai pilihan karena itu konvensional dan tidak ada masalah besar dengan itu?
LEMUEL ADANE
16
@LemuelAdane Fakta bahwa Anda menggunakan gips sama sekali adalah bau kode, tidak masuk akal untuk membuatnya lebih mudah.
Daenyth