Giả sử chúng ta có những điều sau lớp trường hợp và loại bí danh:
scala> case class Foo[A](a: A)
defined class Foo
scala> type F = Foo[_]
defined type alias F
Chúng ta có thể bây giờ (không phải là rất hữu ích) tạo ra một danh sách những thứ kiểu F
:
scala> val foos: List[F] = List(Foo(1), Foo("a"), Foo('a))
foos: List[F] = List(Foo(1), Foo(a), Foo('a))
Và chúng ta có thể tắt chức năng này vào một mảng:
scala> foos.toArray
res0: Array[F] = Array(Foo(1), Foo(a), Foo('a))
Vì vậy, rõ ràng trình biên dịch có thể tìm thấy những biểu hiện nó cần như một tham số ngầm đến toArray
phương pháp trên List
. Nhưng nếu chúng ta yêu cầu một đồng bằng cũ Manifest
cho F
, chúng tôi nhận được một lỗi:
scala> manifest[F]
<console>:11: error: overloaded method value classType with alternatives:
(prefix: scala.reflect.Manifest[_],clazz: Class[_],args: scala.reflect.Manifest[_]*)scala.reflect.Manifest[F] <and>
(clazz: Class[F],arg1: scala.reflect.Manifest[_],args: scala.reflect.Manifest[_]*)scala.reflect.Manifest[F] <and>
(clazz: Class[_])scala.reflect.Manifest[F]
cannot be applied to (java.lang.Class[Foo[_$1]], scala.reflect.Manifest[_$1])
manifest[F]
Vì vậy, rõ ràng là trình biên dịch là có vấn đề khi dùng biểu hiện để đại diện cho ký tự đại diện trong loại bí danh của chúng tôi.
Lý do toArray
hoạt động là nó dự kiến là ClassManifest
, không chỉ là Manifest
. Và trên thực tế, chúng tôi có thể nhận được ClassManifest
cho F
không có vấn đề gì, chính xác vì ClassManifest
sử dụng OptManifest
để thể hiện các đối số loại — không giống như Manifest
, đối số kiểu của nó chỉ là những thứ khác thuộc loại Manifest
.
scala> classManifest[F]
res2: ClassManifest[F] = Foo[<?>]
Đó <?>
là chuỗi đại diện của NoManifest
. Nó đóng vai trò là None
ở đây, cho phép trình biên dịch đại diện cho thông tin lớp về loại F
(đó là tất cả chúng ta cần để tạo một mảng, may mắn thay), mà không nói bất cứ điều gì về các đối số kiểu của F
ngoài "không, tôi có thể" t mô hình đó ".