Scala classOf cho tham số kiểu


80

Tôi đang cố gắng tạo một phương thức chung cho các bản cập nhật đối tượng bằng cách sử dụng scala / java nhưng tôi không thể lấy lớp cho tham số kiểu.

Đây là mã của tôi:

object WorkUnitController extends Controller {     
 def updateObject[T](toUpdate: T, body: JsonObject){
  val source = gson.fromJson(body, classOf[T]);
  ...
 }
}

Lỗi tôi nhận được là

loại lớp bắt buộc nhưng T tìm thấy

Tôi biết trong java bạn không thể làm điều đó nhưng điều này có thể xảy ra trong scala không?

Cảm ơn!


Câu trả lời:


93

Do Manifest được phản (Kể từ Scala 2.10.0) này là câu trả lời được cập nhật -

import scala.reflect.ClassTag
import scala.reflect._

object WorkUnitController extends Controller {
  def updateObject[T: ClassTag](toUpdate: T, body: JsonObject){
    val source = gson.fromJson(body, classTag[T].runtimeClass)
    ???
  }
}

Bạn nên sử dụng ClassTagthay vì ClassManifest.runtimeClassthay vì.erasure

Câu trả lời ban đầu - Có, bạn có thể làm điều đó bằng cách sử dụng tệp kê khai:

object WorkUnitController extends Controller {     
 def updateObject[T: ClassManifest](toUpdate: T, body: JsonObject){
  val source = gson.fromJson(body, classManifest[T].erasure);
  ...
 }
}

Ôi trời thật tuyệt vời! Tôi ước gì tôi biết về điều này sớm hơn!
Darkzaelus

1
Bạn thậm chí có thể viết manifest[T]thay vì implicitly[Manifest[T]].
Jean-Philippe Pellet

1
@ mericano1 họ đã trở thành một phần thiết yếu của ngôn ngữ, và, tôi nghĩ rằng, Manifests không còn là một tính năng thử nghiệm
Vasil Remeniuk

12
@ mericano1 Một bản cập nhật: ManifestClassManifesthiện không được dùng nữa, đã được thay thế bằng TypeTagClassTag, tương ứng, trên Scala 2.10.
Daniel C. Sobral

9
Thay vì classTag[T].runtimeClasstôi cần classTag[T].runtimeClass.asInstanceOf[Class[T]]. Có ai biết tại sao không?
kosii

6

Câu trả lời của Vasil và Maxim đã giúp tôi.

Cá nhân tôi thích cú pháp implicitđược sử dụng để thêm các tham số như vậy (được trình bày : ClassTaglà viết tắt của nó. Vì vậy, ở đây, trong trường hợp ai đó cũng thấy đây là cách tốt hơn:

import scala.reflect.ClassTag

object WorkUnitController extends Controller {
  def updateObject[T](toUpdate: T, body: JsonObject)(implicit tag: ClassTag[T]){
    val source = gson.fromJson(body, tag.runtimeClass)
    ???
  }
}

Tuyên bố từ chối trách nhiệm: Tôi đã không biên dịch ở trên, nhưng mã tương tự của riêng tôi hoạt động theo cách này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.