Scala到Java类型约束的转换问题

Scala到Java类型约束的转换问题,scala,generics,scala-java-interop,Scala,Generics,Scala Java Interop,我有一系列Java类作为Java类的包装器,例如Integer、String、ZonedDateTime等,我将它们放入这个类型接口,其中T是实际的底层Java类型 还有一个类叫做:final class Field 最后,我有一个如下的生成器界面 类数据生成器{ 数据生成器附加项(字段,T值){ 归还这个; } } 这在Java端调用时非常有效: publicstaticvoidmain(字符串[]args){ 字段1=新字段(); 字段2=新字段(); Map Map=newhashmap

我有一系列Java类作为Java类的包装器,例如Integer、String、ZonedDateTime等,我将它们放入这个
类型
接口,其中
T
是实际的底层Java类型

还有一个类叫做:
final class Field

最后,我有一个如下的生成器界面

类数据生成器{
数据生成器附加项(字段,T值){
归还这个;
}
}
这在Java端调用时非常有效:

publicstaticvoidmain(字符串[]args){
字段1=新字段();
字段2=新字段();
Map Map=newhashmap();
地图放置(字段1,“abc”);
map.put(field2,true);
DataBuilder DataBuilder=新的DataBuilder();
forEach(dataBuilder::addEntry);
系统输出打印号(“良好”);
}
从Scala端调用此函数会引起一些问题

objecthello扩展应用程序{
val field1=新字段[字符串,StringType]
val field2=新字段[java.lang.Boolean,BooleanType]
val map=map(
字段1->“abc”,
field2->boolean2Boolean(真)
)
val-dataBuilder:dataBuilder=新的dataBuilder
map.foreach{case(key,value)=>dataBuilder.addEntry(key,value)}
}
这给了我三个错误:


Error:(14,50)推断类型参数[Compariable[\u>:Boolean with String:Boolean with StringErr,我想这是可行的?它基本上是Java代码,除了一些hackery类型是显式的

// The forSome type is not inferred
// Instead, I think this is where the wonky Comparable[_ >: What with Even <: Is] with This type comes from
val map = Map[Field[T, U] forSome { type T; type U <: Type[T] }, Any](
  field1 -> "abc",
  field2 -> boolean2Boolean(true)
  // field2 -> new AnyRef // works, there's no checking
)
val dataBuilder = new DataBuilder
// we know that key: Field[T, U] forSome { type T; type U <: Type[T] }
// the second match doesn't *do* anything, but it lets us name these
// two types something (here, t, u) and use them as type arguments to addEntry
map.foreach { case (key, value) => key match {
  case key: Field[t, u] => dataBuilder.addEntry[t, u](key, value.asInstanceOf[t])
} }
//未推断forSome类型
//相反,我认为这是不可靠的可比性的地方:即使是boolean2Boolean(真的)
//field2->new AnyRef//有效,无需检查
)
val dataBuilder=新的dataBuilder
//我们知道键:字段[T,U]对于某些{typet;typeu,可以使用“异构映射”。异构映射是一种键和值可能具有不同类型的映射。我不知道现有的任何类型安全异构映射实现能够满足您的需求,但这里有一个非常简单的实现。我认为您真正想要的是在这个有趣的映射上使用标准收集操作的能力,以及应该有帮助

import scala.language.existentials
import scala.collection._

class HMap[K[_], V[_]](underlying: immutable.Map[K[_], V[_]] = immutable.Map.empty[K[_], V[_]])
  extends Iterable[(K[T], V[T]) forSome { type T }]
     with IterableOps[(K[T], V[T]) forSome { type T }, Iterable, HMap[K, V]] {
  // collections boilerplate
  override protected def fromSpecific(coll: IterableOnce[(K[T], V[T]) forSome { type T }]): HMap[K, V]
  = new HMap[K, V](immutable.Map.from(coll))
  override protected def newSpecificBuilder: mutable.Builder[(K[T], V[T]) forSome { type T }, HMap[K, V]]
  = immutable.Map.newBuilder[K[_], V[_]].mapResult(new HMap[K, V](_))
  override def empty: HMap[K, V] = new HMap[K, V]
  override def iterator: Iterator[(K[T], V[T]) forSome { type T }]
  = new Iterator[(K[T], V[T]) forSome { type T }] {
    val underlying = HMap.this.underlying.iterator
    override def hasNext: Boolean = underlying.hasNext
    override def next(): (K[T], V[T]) forSome { type T }
    = underlying.next().asInstanceOf[(K[T], V[T]) forSome { type T}]
  }

  // Mappy operations
  def get[T](k: K[T]): Option[V[T]] = underlying.get(k).map(_.asInstanceOf[V[T]])
  def +[T](kv: (K[T], V[T])): HMap[K, V] = new HMap[K, V](underlying + kv)
  def -[T](k: K[T]): HMap[K, V] = new HMap[K, V](underlying - k)
}
object HMap {
  // Mappy construction
  def apply[K[_], V[_]](elems: (K[T], V[T]) forSome { type T }*): HMap[K, V] = new HMap[K, V](immutable.Map(elems: _*))
}
现在一切都很顺利

type FieldOf[T] = Field[T, _ <: Type[T]]
type Id[T] = T
val map = HMap[FieldOf, Id](
  field1 -> "abc",
  field2 -> boolean2Boolean(true)
  // field2 -> new AnyRef // doesn't work, readable(-ish) error message
)
val dataBuilder = new DataBuilder
map.foreach { case (key, value) => dataBuilder.addEntry(key, value) }

(在需要时进行更多更改)

当目标是保留类型时,使用
Any
浏览
Map
很少是一个好主意(之后供构建者使用)使用映射来保存这些对的原因是为了代码的可重用性:我还想把整个
map
记录下来。我的编译器无法识别
字段[t,u]
is.Typechecker抱怨存在类型的使用,并说它可能很快就会消失……有没有办法使用存在类型?绑定类型变量非常挑剔,但Scala 2.13可以很好地处理这段代码。如果您想删除存在类型,因为这段代码甚至都不安全,只需将键类型设置为o对于
映射
字段[\uu,\u]
。这会降低精确度,但如果你不在意,那也没关系。如果你在意,你就必须创建一个包装类
隐式类FieldOf[t](val Field:Field[t),实际上,仔细想想,如果对存在主义的替换最终像在Dotty,
字段[\uu]中那样工作的话
实际上将与此处键入的某些
相同。因此,真的不必担心。
case class Prod[K[_], V[_], T](k: K[T], v: V[T])
object Prod {
    implicit def fromTup2[K[_], V[_], T](kv: (K[T], V[T])): Prod[K, V]
    = Prod(kv._1, kv._2)
}