代码之家  ›  专栏  ›  技术社区  ›  Craig P. Motlin

Scala类型构造函数

  •  6
  • Craig P. Motlin  · 技术社区  · 14 年前

    我正在尝试编写一个方法,它接受一个Map[K,Collection[V]],并将其转换为一个Map,其值具有不同类型的集合。该方法使用“multimap”和一个构建器来构建新集合。我是这样用的:

    val multimap = new java.util.HashMap[Int, java.util.List[String]]
    multimap.put(1, Arrays.asList("One"))
    multimap.put(2, Arrays.asList("Two", "Three"))
    
    val mapOfLists: java.util.Map[Int, java.util.Set[String]] =
        asMap(multimap, Builder.SET)
    

    以下是建设者的样子:

    trait Builder[C[_] <: java.util.Collection[_]]
    {
        def create[V]: C[V]
    }
    
    object Builder
    {
        val SET = new Builder[java.util.Set]()
        {
            def create[V]: java.util.Set[V] = new java.util.HashSet[V]
        }
    }
    

    下面是asMap()的实现。行得通,但我不明白- 为什么我需要最后的类型转换?

    def asMap[K, V, C[_] <: java.util.Collection[_]](
            multimap: java.util.Map[K, _ <: java.util.Collection[V]], builder: Builder[C]): java.util.Map[K, C[V]] =
    {
        val result = new java.util.HashMap[K, C[V]]
        val iterator: Iterator[K] = multimap.keySet.iterator
        while (iterator.hasNext)
        {
            val key = iterator.next
            val collection: C[V] = builder.create[V]
            collection.asInstanceOf[java.util.Collection[V]].addAll(multimap.get(key))
            result.put(key, collection)
        }
        result
    }
    

    如果没有类型case,我会得到以下错误:

    [ERROR] error: type mismatch;
    [INFO]  found   : java.util.Collection[V]
    [INFO]  required: java.util.Collection[_ <: _$2] where type _$2
    [INFO]             collection.addAll(multimap.get(key))
    
    1 回复  |  直到 14 年前
        1
  •  8
  •   Moritz    14 年前

    您不小心创建了存在类型而不是类型构造函数。有效的类型构造函数是 C[X] <: Collection[X| 所以你需要改变 Builder

    trait Builder[C[X] <: Collection[X]] {
        def create[V]: C[V]
    }
    

    以及 asMap

    def asMap[K, V, C[X] <: Collection[X]](multimap: Map[K, _ <: Collection[V]],
      builder: Builder[C]): Map[K, C[V]]