Yang saya tahu tentang TypeTag adalah mereka entah bagaimana menggantikan Manifest. Informasi di Internet langka dan tidak memberi saya pengertian yang baik tentang subjek.
Jadi saya akan senang jika seseorang membagikan tautan ke beberapa materi berguna di TypeTag termasuk contoh dan kasus penggunaan populer. Jawaban dan penjelasan terperinci juga diterima.
scala
types
scala-2.10
reification
Sergey Weiss
sumber
sumber
Jawaban:
A
TypeTag
memecahkan masalah bahwa tipe Scala dihapus pada saat runtime (type erasure). Jika kita ingin melakukannyakami akan mendapat peringatan:
Untuk mengatasi masalah ini, Manifes diperkenalkan ke Scala. Tetapi mereka memiliki masalah karena tidak dapat mewakili banyak tipe yang berguna, seperti tipe path-dependen:
Dengan demikian, mereka digantikan oleh TypeTags , yang keduanya lebih mudah digunakan dan terintegrasi dengan baik ke dalam API Refleksi baru. Dengan mereka, kita dapat memecahkan masalah di atas tentang tipe path-dependent secara elegan:
Mereka juga mudah digunakan untuk memeriksa parameter tipe:
Pada titik ini, sangat penting untuk memahami penggunaan
=:=
(jenis kesetaraan) dan<:<
(hubungan subtipe) untuk pemeriksaan kesetaraan. Jangan pernah menggunakan==
atau!=
, kecuali jika Anda benar-benar tahu apa yang Anda lakukan:Yang terakhir memeriksa kesetaraan struktural, yang sering kali bukan apa yang harus dilakukan karena tidak peduli tentang hal-hal seperti awalan (seperti dalam contoh).
A
TypeTag
sepenuhnya dihasilkan oleh kompiler, artinya kompiler membuat dan mengisiTypeTag
ketika seseorang memanggil metode yang mengharapkan aTypeTag
. Ada tiga bentuk tag yang berbeda:ClassTag
penggantiClassManifest
sedangkanTypeTag
kurang lebih penggantiManifest
.Yang pertama memungkinkan untuk sepenuhnya bekerja dengan array generik:
ClassTag
hanya menyediakan informasi yang diperlukan untuk membuat tipe saat runtime (yang merupakan tipe terhapus):Seperti yang dapat dilihat di atas, mereka tidak peduli tentang penghapusan tipe, oleh karena itu jika seseorang ingin tipe "penuh"
TypeTag
harus digunakan:Seperti yang dapat dilihat, metode
tpe
dariTypeTag
hasil dalam penuhType
, yang sama kita dapatkan ketikatypeOf
disebut. Tentu saja, dimungkinkan untuk menggunakan keduanya,ClassTag
danTypeTag
:Pertanyaan yang tersisa sekarang adalah apa artinya
WeakTypeTag
? Singkatnya,TypeTag
merupakan tipe beton (ini berarti hanya memungkinkan tipe instantiated sepenuhnya) sedangkanWeakTypeTag
hanya memungkinkan jenis apa pun. Sebagian besar waktu seseorang tidak peduli yang mana (yang berartiTypeTag
harus digunakan), tetapi misalnya, ketika makro digunakan yang harus bekerja dengan jenis generik mereka diperlukan:Jika seseorang mengganti
WeakTypeTag
denganTypeTag
kesalahan dilemparkan:Untuk penjelasan yang lebih terperinci tentang perbedaan antara
TypeTag
danWeakTypeTag
melihat pertanyaan ini: Scala Macros: "tidak dapat membuat TypeTag dari tipe T yang memiliki parameter tipe yang belum terselesaikan"Situs dokumentasi resmi Scala juga berisi panduan untuk Refleksi .
sumber
==
untuk tipe mewakili kesetaraan struktural, bukan referensi kesetaraan.=:=
memperhitungkan kesetaraan jenis akun (bahkan yang tidak jelas seperti kesetaraan awalan yang berasal dari mirror yang berbeda), 2) KeduanyaTypeTag
danAbsTypeTag
didasarkan pada mirror. Perbedaannya adalah bahwaTypeTag
hanya memungkinkan tipe instantiated sepenuhnya (yaitu tanpa parameter tipe atau referensi anggota tipe abstrak), 3) Penjelasan terperinci di sini: stackoverflow.com/questions/12093752Int
dan tipe generik sepertiList[Int]
), meninggalkan tipe Scala seperti misalnya penyempitan, tipe path-dependent, eksistensial, tipe beranotasi. Manifes juga merupakan baut, sehingga mereka tidak dapat menggunakan pengetahuan luas yang dimiliki oleh kompiler untuk, katakanlah, menghitung linierisasi suatu jenis, mencari tahu apakah satu jenis subtipe lainnya, dll.Types.scala
(7 kloc kode yang tahu bagaimana jenis didukung untuk bekerja bersama),Symbols.scala
(3 kloc kode yang tahu bagaimana tabel simbol bekerja), dll.ClassTag
adalah pengganti drop-in yang tepat untukClassManifest
, sedangkanTypeTag
lebih atau kurang merupakan penggantiManifest
. Lebih atau kurang, karena: 1) tag jenis tidak membawa penghapusan, 2) manifes adalah hack besar, dan kami menyerah meniru perilakunya dengan tag ketik. # 1 dapat diperbaiki dengan menggunakan kedua konteks ClassTag dan TypeTag batas ketika Anda membutuhkan penghapusan dan jenis, dan satu biasanya tidak peduli tentang # 2, karena menjadi mungkin untuk membuang semua peretasan dan menggunakan API refleksi penuh sebagai gantinya.