2013-06-11 3 views
3

Scala 프로젝트에서 JSON을 직렬화/비 직렬화하기 위해 Argonaut (http://argonaut.io)를 래핑하려고합니다. 우리는 이전에 Jerkson을 사용했으나 중단 된대로 대안을 찾고 있습니다. 내가 노력하고 내가 다음과 같은 오류를 얻을이를 컴파일 할 때일반 유형을 Argonaut에 전달하는 방법

이 기본 JSON 래퍼

import argonaut._, Argonaut._ 

object Json { 
    def Parse[T](input: String): T = { 
    input.decodeOption[T].get 
    } 
} 

입니다.

could not find implicit value for evidence parameter of type argonaut.DecodeJson[T] 
    input.decodeOption[T] 
       ^
not enough arguments for method decodeOption: (implicit evidence$6: argonaut.DecodeJson[T]) Option[T]. 
Unspecified value parameter evidence$6. 
    input.decodeOption[T] 
       ^

내가 잘못하고있는 것에 대해이 포인터 또는 포인터를 수정하는 방법에 대한 제안 사항이 가장 만족 스러울 것입니다.

대체 JSON 프레임 워크에 대한 제안도 환영합니다.

저는 스칼라/자바에 대해 처음 접했고 제네릭은 어떻게 작동합니까? 몇 년 동안 .NET/C#을 작성했습니다.

+0

decodeOption이 Option을 반환한다고 가정하지만, 메소드가 T. –

+0

에게 감사를 표시합니다. 예제에서 .get을 추가하는 것을 잊었습니다. –

답변

7

코드를 작동하게하기 위해, 당신은 너무처럼 Json 개체를 다시 정의해야합니다

object Json { 
    def Parse[T](input: String)(implicit decode:DecodeJson[T]): Option[T] = { 
    input.decodeOption[T] 
    } 
} 

를 누락 한 것은이 decodeOption 기능을 파악하기 위해 필요로하는 암시 DecodeJson 예를했습니다 해독하는 방법. 또한 T 대신 반환 유형을 Option[T]으로 정의해야합니다.이 모든 작업의 ​​전체 예는 다음과 같습니다

import argonaut._, Argonaut._ 
case class User(id:Long, email:String, name:String) 

object Json { 
    def Parse[T](input: String)(implicit decode:DecodeJson[T]): Option[T] = { 
    input.decodeOption[T] 
    } 
} 

object JsonTest{ 
    implicit val userDecode = casecodec3(User.apply, User.unapply)("id", "email", "name") 

    def main(args: Array[String]) { 
    val json = """{ 
     "id": 1, 
     "email": "[email protected]", 
     "name": "foo bar" 
    }""" 

    val userOpt = Json.Parse[User](json) 
    println(userOpt) 
    } 
} 

지금까지 다른 JSON 프레임 워크로, 당신은으로 볼 수 있었다 :

Play Json

json4s

spray-json

Jackson Scala Module

3

Argonaut는 거의 모든 스칼라 직렬화 라이브러리와 마찬가지로 유형 클래스 패턴을 사용합니다. 이것은 멋진 것 같지만 실제로는 T 유형의 객체를 serialize/deserialize 할 때 프로세스의 일부 또는 전부가 연기되는 다른 객체의 인스턴스를 암시 적으로 전달해야한다는 것을 의미합니다. 특히 decodeOption[T]을 수행 할 때 argonaut.DecodeJson[T] (decodeOption은 비 직렬화 중에 사용함)의 범위에 있어야합니다.

def Parse[T](input: String)(implicit decoder: argonaut.DecodeJson[T]): Option[T] = { 
    input.decodeOption[T] 
} 

스칼라도 (선언이 짧게 몇 가지 문법 설탕을 제공합니다 : 당신은 무엇을해야

(이것은 자동으로 decodeOption에 전달됩니다 Parse에 전달이 암시 적 값을 요구하는 것입니다 이것은 "컨텍스트 바인딩")라고 : Parse를 호출 할 때 지금

def Parse[T:argonaut.DecodeJson](input: String): Option[T] = { 
    input.decodeOption[T] 
} 

는, 당신은 argonaut.DecodeJson의 범위에 내재 된 가치를 제공해야합니다, 또는 그것은 칼은 C에 실패합니다 ompile. 분명히 Argonaut 객체는 이미 많은 표준 유형에 대한 디코더를 이미 정의 했으므로 특별한 유형은 필요하지 않습니다. 다른 유형 (예 : 사용자 정의 유형)의 경우, 디코더를 정의하고이를 암시 적으로 가져와야합니다.

관련 문제