Как сделать только несколько типов данных, которые не связаны друг с другом, приемлемыми для генериков - PullRequest
0 голосов
/ 02 июля 2018

Есть черта, которая работает отлично. Тем не менее, я хотел бы реорганизовать часть, относящуюся к generic [T], чтобы ограничить тип данных, который может быть принят generic [T] (мне нужны только Option [JsValue], JsValue, StringEnumEntry, String). Можно ли решить эту проблему с помощью бесформенного побочного продукта? Может быть есть другие решения?

trait ParameterBinders extends Log {

  def jsonBinder[T](json: T, jsonType: java.lang.String = "json"): ParameterBinderWithValue = {
    val jsonObject = new PGobject()
    jsonObject.setType(jsonType)
    json match {
      case json: Option[JsValue] =>
        jsonObject.setValue(json.map(Json.stringify).orNull)
      case json: JsValue =>
        jsonObject.setValue(Json.stringify(json))
      case json: StringEnumEntry =>
        jsonObject.setValue(json.value)
      case json: String =>
        jsonObject.setValue(json)
      case _ =>
        logger.error("unexpected data type ")
    }
    if (jsonType == "JSONSCHEMATYPE" || jsonType == "SYSPROPERTYTYPE") {
      ParameterBinder(this, (ps, i) => {
        ps.setObject(i, jsonObject)
      })
    } else {
      ParameterBinder(json, (ps, i) => {
        ps.setObject(i, jsonObject)
      })
    }

  }
}

1 Ответ

0 голосов
/ 02 июля 2018

Самый простой способ - использовать ADT, как описано в ссылке первого комментария. Если вы не хотите изменять типы, принятые в jsonBinder, вы можете решить эту проблему, используя класс типов.

, например

trait JsonBindValue[T] {
    def value(t: T): String
}

тогда вам нужно будет предоставить экземпляры для ваших принятых типов данных

object JsonBindValue {
    implicit val OptJsBinder = new JsonBindValue[Option[JsValue]] {
        def value(t: Option[JsValue]): String = {
            t.map(Json.stringify).orNull
        }
    }
   ... more instances here
}

наконец, ваша функция будет выглядеть так:

def jsonBinder[T : JsonBindValue](json: T, jsonType: java.lang.String = "json"): ParameterBinderWithValue = {
    val binder = implicitly[JsonBindValue[T]]
    jsonObject.setType(jsonType)
    jsonObject.setValue(binder.value(json))
    ...
}

если вы вызовете функцию без неявного экземпляра в области видимости, вы получите ошибку времени компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...