java - Array map() 期间令人困惑的隐式转换

标签 java arrays scala implicit-conversion implicit

我有一个用例,其中给我一个包装类的 Java 数组,例如包装一个 int,并且我想将它们转换为相同数据的 ValueSet,但我遇到了隐式转换的令人费解的问题。这是我尝试做的 Java 和 Scala 的示例:

.../java/demoapi/SomeWrapper.java

package demoapi;

public class SomeWrapper {
    public static final int JavaOne = 1;
    public static final int JavaTwo = 2;
    public int m_theInt;
};

.../scala/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
    }
  }
}

map 无法编译并出现以下错误:

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,但我还没有达到这一点。

最佳答案

您希望将数组转换为集合 (ArrayOps),以便可以对其进行操作。

但是您希望生成一个 ValueSet,为此,机器需要一种构建它的方法,即 CanBuildFrom。

此处隐式提供:

See the docs for ValueSet .

由于您提供了一种将数组转换为 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)

关于java - Array map() 期间令人困惑的隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25072356/

相关文章:

javascript - VueJs - DOM 不更新数组突变

scala - Apache Livy 不适用于本地 jar 文件

scala - 貘自定义编解码器

java - 如果使用 @Local 注释 (EJB),则会出错

java - 在 ObjectInputStream 上调用 readObject() 时获取 java.io.EOFException

java - 如何有效地从 Android 上的资源中获取短数组?

php json_encode 为数组返回空白

scala - 如何在 sbt 下使用 Quasar 和 Scala?

java - JMS 消息传递性能 : Lots of Topics/Queues vs. 广泛过滤(消息选择器)

java - 我如何知道java程序需要运行哪些jar文件?