没有类型的隐式参数:任何
No Implicit arguments of Type: Any
我关注了这篇文章create union types。这些文章对原始类型的回答很少,但我的场景是对其的扩展。
所以,我正在尝试定义一个采用 Map[String, A]
的方法,其中 A 是允许类型的集合。
这是我的 class 联合类型:
sealed trait SupportedType[A]
object SupportedType {
implicit val byteBufferColumn : SupportedType[ByteBuffer] = new SupportedType[ByteBuffer] {}
implicit val longColumn : SupportedType[java.lang.Long] = new SupportedType[java.lang.Long] {}
implicit val byteArrayColumn : SupportedType[Array[Byte]] = new SupportedType[Array[Byte]] {}
implicit val stringColumn : SupportedType[String] = new SupportedType[String] {}
}
这是我定义的方法:
def upsert[A: SupportedType](key: T, values: Map[String, A], timestamp: Long, ttl: Duration): Future[Unit]
我是这样调用方法的:
dataStore.upsert(
cacheKey,
Map(
itColumn -> ByteBuffer.wrap(Utils.compress(iti.toByteArray)),
cacheWriteTimeColumn -> writeTime.toEpochMilli
),
writeTime.toEpochMilli,
ttl
)
错误:No implicit arguments of type: SupportedType[Any]
我的猜测是 writeTime.toEpochMilli returns java.long 类型,正如您在 SupportedType 中看到的那样,我尝试定义 java.lang.Long
但那是行不通的。
如有任何帮助,我们将不胜感激。
您可以将 magnet 模式与 typeclass 组合使用,如下所示:
import scala.language.implicitConversions
trait ColumnValue {
def serialize(): String
}
object ColumnValue {
trait SupportedType[A] {
def toColumn(a: A): ColumnValue
}
object SupportedType {
implicit final val stringSupportedType: SupportedType[String] =
new SupportedType[String] {
override def toColumn(str: String): ColumnValue =
new ColumnValue {
override def serialize(): String =
"\"" + str + "\""
}
}
implicit final val intSupportedType: SupportedType[Int] =
new SupportedType[Int] {
override def toColumn(int: Int): ColumnValue =
new ColumnValue {
override def serialize(): String =
int.toString
}
}
implicit final val booleanSupportedType: SupportedType[Boolean] =
new SupportedType[Boolean] {
override def toColumn(bool: Boolean): ColumnValue =
new ColumnValue {
override def serialize(): String =
if (bool) "1" else "0"
}
}
implicit final def listSupportedType[A](implicit ev: SupportedType[A]): SupportedType[List[A]] =
new SupportedType[List[A]] {
override def toColumn(list: List[A]): ColumnValue =
new ColumnValue {
override def serialize(): String =
list.map(a => ev.toColumn(a).serialize()).mkString("[", ",", "]")
}
}
}
def apply[A](a: A)(implicit ev: SupportedType[A]): ColumnValue =
ev.toColumn(a)
implicit def supportedType2Column[A : SupportedType](a: A): ColumnValue =
apply(a)
}
You may create some helper functions to reduce some of the boilerplate.
可以这样使用:
final case class Table(data: Map[String, ColumnValue]) {
def upsert(values: Map[String, ColumnValue]): Table =
copy(this.data ++ values)
}
object Table {
val empty: Table =
Table(data = Map.empty)
}
val result = Table.empty.upsert(Map(
"a" -> "foo",
"b" -> 10,
"c" -> List(true, false, true)
))
见代码运行here.
我关注了这篇文章create union types。这些文章对原始类型的回答很少,但我的场景是对其的扩展。
所以,我正在尝试定义一个采用 Map[String, A]
的方法,其中 A 是允许类型的集合。
这是我的 class 联合类型:
sealed trait SupportedType[A]
object SupportedType {
implicit val byteBufferColumn : SupportedType[ByteBuffer] = new SupportedType[ByteBuffer] {}
implicit val longColumn : SupportedType[java.lang.Long] = new SupportedType[java.lang.Long] {}
implicit val byteArrayColumn : SupportedType[Array[Byte]] = new SupportedType[Array[Byte]] {}
implicit val stringColumn : SupportedType[String] = new SupportedType[String] {}
}
这是我定义的方法:
def upsert[A: SupportedType](key: T, values: Map[String, A], timestamp: Long, ttl: Duration): Future[Unit]
我是这样调用方法的:
dataStore.upsert(
cacheKey,
Map(
itColumn -> ByteBuffer.wrap(Utils.compress(iti.toByteArray)),
cacheWriteTimeColumn -> writeTime.toEpochMilli
),
writeTime.toEpochMilli,
ttl
)
错误:No implicit arguments of type: SupportedType[Any]
我的猜测是 writeTime.toEpochMilli returns java.long 类型,正如您在 SupportedType 中看到的那样,我尝试定义 java.lang.Long
但那是行不通的。
如有任何帮助,我们将不胜感激。
您可以将 magnet 模式与 typeclass 组合使用,如下所示:
import scala.language.implicitConversions
trait ColumnValue {
def serialize(): String
}
object ColumnValue {
trait SupportedType[A] {
def toColumn(a: A): ColumnValue
}
object SupportedType {
implicit final val stringSupportedType: SupportedType[String] =
new SupportedType[String] {
override def toColumn(str: String): ColumnValue =
new ColumnValue {
override def serialize(): String =
"\"" + str + "\""
}
}
implicit final val intSupportedType: SupportedType[Int] =
new SupportedType[Int] {
override def toColumn(int: Int): ColumnValue =
new ColumnValue {
override def serialize(): String =
int.toString
}
}
implicit final val booleanSupportedType: SupportedType[Boolean] =
new SupportedType[Boolean] {
override def toColumn(bool: Boolean): ColumnValue =
new ColumnValue {
override def serialize(): String =
if (bool) "1" else "0"
}
}
implicit final def listSupportedType[A](implicit ev: SupportedType[A]): SupportedType[List[A]] =
new SupportedType[List[A]] {
override def toColumn(list: List[A]): ColumnValue =
new ColumnValue {
override def serialize(): String =
list.map(a => ev.toColumn(a).serialize()).mkString("[", ",", "]")
}
}
}
def apply[A](a: A)(implicit ev: SupportedType[A]): ColumnValue =
ev.toColumn(a)
implicit def supportedType2Column[A : SupportedType](a: A): ColumnValue =
apply(a)
}
You may create some helper functions to reduce some of the boilerplate.
可以这样使用:
final case class Table(data: Map[String, ColumnValue]) {
def upsert(values: Map[String, ColumnValue]): Table =
copy(this.data ++ values)
}
object Table {
val empty: Table =
Table(data = Map.empty)
}
val result = Table.empty.upsert(Map(
"a" -> "foo",
"b" -> 10,
"c" -> List(true, false, true)
))
见代码运行here.