我有一个用例,我给了一个包装类的Java数组,例如,包装一个int,我想将它们转换为相同数据的ValueSet,但是我遇到了隐含转换的一个令人费解的问题。这是我尝试做的Java和Scala的一个例子:
... /爪哇/ demoapi / SomeWrapper.java
package demoapi;
public class SomeWrapper {
public static final int JavaOne = 1;
public static final int JavaTwo = 2;
public int m_theInt;
};
... /阶/ demo.scala
package demotest
import demoapi._
object TestEnum extends Enumeration {
val One, Two = Value
}
object SomeWrapperEx {
implicit def fromJava(in: Array[SomeWrapper]): TestEnum.ValueSet = {
in.map(x => fromInt(x.m_theInt))
}
def fromInt(in: Int): TestEnum.Value = {
in match {
case SomeWrapper.JavaOne => TestEnum.One
case SomeWrapper.JavaTwo => TestEnum.Two
}
}
}
地图无法编译,出现以下错误:
Error:(11, 27) value m_theInt is not a member of demotest.TestEnum.Value
in.map(x => fromInt(x.m_theInt))
^
我的问题是:数组元素的类型如何转换为TestEnum.Value?我不得不通过放弃这些隐含的方式来解决这些问题,但我觉得这应该以某种方式起作用......
编辑:我确信我需要做的更多才能让它工作,例如可能将Array [TestEnum.Value]转换为ValueSet,但我还没有达到这一点。答案 0 :(得分:1)
您希望将Array转换为集合(ArrayOps),以便对其进行操作。
但是你期望生成一个ValueSet,为此,机器需要一种方法来构建它,一个CanBuildFrom。
这里隐含地提供了这个:
由于您提供了一种将Array转换为ValueSet的方法,因此很乐意应用它来使用可用的CanBuildFrom。
-Xprint:typer
向您展示了它的方向:
implicit def fromJava(in: Array[demoapi.SomeWrapper]): demoapi.TestEnum.ValueSet = SomeWrapperEx.this.fromJava(in).map[Nothing, demoapi.TestEnum.ValueSet](((x: demoapi.TestEnum.Value) => SomeWrapperEx.this.fromInt(x.<m_theInt: error>)))(demoapi.this.TestEnum.ValueSet.canBuildFrom);
我在使用ValueSet作为普通集合时遇到了问题,所以现在我没有。
例如,始终以ValueSet开头:
$ scala
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_05).
Type in expressions to have them evaluated.
Type :help for more information.
scala> object Days extends Enumeration { val M,T,W,Th,F,Sa,S = Value }
defined object Days
scala> val ds = (2 to 5).toArray
ds: Array[Int] = Array(2, 3, 4, 5)
scala> Days.values filter (ds contains _.id)
res0: Days.ValueSet = Days.ValueSet(W, Th, F, Sa)
或手工构建:
scala> Days.ValueSet.empty
res1: Days.ValueSet = Days.ValueSet()
scala> res1 + Days.T
res2: Days.ValueSet = Days.ValueSet(T)
无论如何都是CanBuildFrom:
scala> implicit val xxx = new collection.generic.CanBuildFrom[Array[Int], Days.Value, Days.ValueSet] {
| def apply() = Days.ValueSet.newBuilder
| def apply(from: Array[Int]) = apply()
| }
xxx: scala.collection.generic.CanBuildFrom[Array[Int],Days.Value,Days.ValueSet] = $anon$1@6b474074
scala> (2 to 5) map (_ => Days.T)
res4: scala.collection.immutable.IndexedSeq[Days.Value] = Vector(T, T, T, T)
scala> (2 to 5) map (Days(_))
res5: scala.collection.immutable.IndexedSeq[Days.Value] = Vector(W, Th, F, Sa)