【发布时间】:2017-07-12 06:25:16
【问题描述】:
我正在编写一个带有三个参数f、from、to 的函数。 f 应该是任何具有 apply 方法的对象,它消耗并产生一个 Int。
def printValues(f: {def apply(n: Int):Int}, from: Int, to: Int) {
for(i <- from to `to`) print(f(i) + " ")
print("\n")
}
我在这里使用结构类型来保证f 有apply() 方法。
当我使用Array[Int] 调用方法printValues() 时,一切顺利。
printValues(Array(1,1,2,3,5,8,13,21,34,55), 3, 6)
我尝试使用 lambda 表达式调用该方法,结果一团糟
printValues((x: Int) => x * x, 3, 6)
错误信息
java.lang.NoSuchMethodException: ch18.p8.Main$$$Lambda$97/474675244.apply(int)
at java.lang.Class.getMethod(Class.java:1786)
at ch18.p8.Main$.reflMethod$Method3(Ch18.scala:270)
at ch18.p8.Main$.$anonfun$printValues$1(Ch18.scala:270)
at scala.runtime.java8.JFunction1$mcII$sp.apply(JFunction1$mcII$sp.java:12)
at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
at scala.collection.immutable.Range.foreach(Range.scala:156)
at scala.collection.TraversableLike.map(TraversableLike.scala:234)
at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at ch18.p8.Main$.printValues(Ch18.scala:270)
at ch18.p8.Main$.delayedEndpoint$ch18$p8$Main$1(Ch18.scala:274)
at ch18.p8.Main$delayedInit$body.apply(Ch18.scala:267)
at scala.Function0.apply$mcV$sp(Function0.scala:34)
at scala.Function0.apply$mcV$sp$(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App.$anonfun$main$1$adapted(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:389)
at scala.App.main(App.scala:76)
at scala.App.main$(App.scala:74)
at ch18.p8.Main$.main(Ch18.scala:267)
at ch18.p8.Main.main(Ch18.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at scala.reflect.internal.util.ScalaClassLoader.$anonfun$run$2(ScalaClassLoader.scala:98)
at scala.reflect.internal.util.ScalaClassLoader.asContext(ScalaClassLoader.scala:32)
at scala.reflect.internal.util.ScalaClassLoader.asContext$(ScalaClassLoader.scala:30)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:129)
at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:98)
at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:90)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:129)
at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:22)
at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:21)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:29)
at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:28)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:61)
at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:88)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:99)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:104)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
我尝试验证对象 lambdaxxx 具有函数 apply(在 Scala REPL 中)
scala> val f = (x: Int) => x * x
f: Int => Int = $$Lambda$1020/826690115@7f8633ae
scala> f.apply
def apply(v1: Int): Int
我收到了两个错误报告:
Seemingly using structural type
所以说不定我也落入了这个陷阱。
顺便说一句,如果printValues()在下面,则lambda表达式可以适合方法printValues2()。
def printValues2(f: (Int) => (Int), from: Int, to: Int) {
for(i <- from to `to`) print(f(i) + " ")
print("\n")
}
感谢您分享您的想法,祝您好运。
【问题讨论】:
-
printValues((x: Int) => x * x, 3, 6) 在 REPL 和 IDEA 中为我工作
-
@Ivan 哪个 Scala 版本? OP 也应该指定它。
-
@lvan 我在 scala-2.9.1(jdk 1.7) 中运行代码,生活很美好。但是,当我回到 scala-2.12.2(jdk 1.8) 时,麻烦就来了。
-
适用于 2.11.11
-
Scala 问题跟踪器中的错误:github.com/scala/bug/issues/10334 和待定修复 github.com/scala/scala/pull/5977,可能会成为 2.12.3 的一部分。
标签: scala lambda nosuchmethoderror structural-typing