Tôi có đoạn mã sau sử dụng bình xịt để deserialise một số JSON vào một lớp chữ thường, thông qua phương thức parseJson
.Scala sử dụng các loại rõ ràng khi giải quyết các vấn đề liên quan như thế nào?
Tùy thuộc vào nơi JsonFormat ngầm định [MyCaseClass] được xác định (nội dòng hoặc được nhập từ đối tượng đồng hành) và liệu có loại rõ ràng được cung cấp khi được xác định hay không, mã có thể không biên dịch.
Tôi không hiểu tại sao việc nhập ẩn từ đối tượng đồng hành yêu cầu nó phải có loại rõ ràng khi được xác định, nhưng nếu tôi đặt nội tuyến thì đây không phải là trường hợp?
Điều thú vị là IntelliJ định vị chính xác các thông số tiềm ẩn (thông qua cmd-shift-p) trong mọi trường hợp.
Tôi đang sử dụng Scala 2.11.7.
bị hỏng Mã - nhập ký tự đại diện từ đối tượng đồng, suy ra loại:
import SampleApp._
import spray.json._
class SampleApp {
import MyJsonProtocol._
val inputJson = """{"children":["a", "b", "c"]}"""
println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}
object SampleApp {
case class MyCaseClass(children: List[String])
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val myCaseClassSchemaFormat = jsonFormat1(MyCaseClass)
}
}
Kết quả trong:
Cannot find JsonReader or JsonFormat type class for SampleAppObject.MyCaseClass
Lưu ý rằng điều tương tự sẽ xảy ra với một khẩu rõ ràng của myCaseClassSchemaFormat
ngầm.
Mã Working # 1 - nhập ký tự đại diện từ đối tượng đồng, loại rõ ràng:
Thêm một loại rõ ràng để các JsonFormat trong đối tượng đồng hành gây ra mã để biên dịch:
import SampleApp._
import spray.json._
class SampleApp {
import MyJsonProtocol._
val inputJson = """{"children":["a", "b", "c"]}"""
println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}
object SampleApp {
case class MyCaseClass(children: List[String])
object MyJsonProtocol extends DefaultJsonProtocol {
//Explicit type added here now
implicit val myCaseClassSchemaFormat: JsonFormat[MyCaseClass] = jsonFormat1(MyCaseClass)
}
}
Working Mã số 2 - Ngụ ý nội dòng, loại được phỏng đoán:
Tuy nhiên, đặt các tham số ngầm trong dòng nơi chúng được sử dụng, mà không cần loại rõ ràng, cũng hoạt động!
import SampleApp._
import spray.json._
class SampleApp {
import DefaultJsonProtocol._
//Now in-line custom JsonFormat rather than imported
implicit val myCaseClassSchemaFormat = jsonFormat1(MyCaseClass)
val inputJson = """{"children":["a", "b", "c"]}"""
println(s"Deserialise: ${inputJson.parseJson.convertTo[MyCaseClass]}")
}
object SampleApp {
case class MyCaseClass(children: List[String])
}
Đây là một trong những câu hỏi "đau khi tôi làm điều này", câu trả lời hay nhất gần như chắc chắn "không làm điều đó". Theo kinh nghiệm của tôi, các giá trị tiềm ẩn thiếu chú thích kiểu là một trong những nguồn gây nhầm lẫn phổ biến nhất, sự khác biệt giữa các phiên bản lạ trong hành vi, vv, trong Scala. –
Hi Travis - thực sự, đây là một lỗi thú vị để làm việc xung quanh, nhưng tôi đoán chú thích loại thời gian tiếp theo sẽ là cổng gọi đầu tiên của tôi cho các vấn đề tương tự! Không chắc chắn nếu điều này được coi là một lỗi Scala hay không, nhưng có thể đặt một cái gì đó vào danh sách gửi thư/xem xét nâng cao một vấn đề chỉ trong trường hợp. – MrProper
Trình biên dịch đưa ra một thông báo lỗi nói rằng 'phương pháp ngầm không có gì áp dụng ở đây vì nó xuất hiện sau điểm ứng dụng và nó thiếu một kiểu kết quả rõ ràng' vì vậy ít nhất là lỗi nhỏ để chẩn đoán và sửa lỗi :) – Hugh