代码之家  ›  专栏  ›  技术社区  ›  Tim Florian

如何使泛型只接受少数相互不相关的数据类型

  •  3
  • Tim Florian  · 技术社区  · 6 年前

    有一种特质是完美的。但是,我想重构与generic[t]相关的部分,以限制generic[t]可以接受的数据类型(我只需要选项[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 回复  |  直到 6 年前
        1
  •  2
  •   fusion    6 年前

    最简单的方法是使用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))
        ...
    }
    

    如果在作用域中调用没有隐式实例的函数,则会得到编译时错误。