我如何摆脱这种类型的警告/错误?
我有一个剧本。它运行时没有警告。
$ cat ~/tmp/so1.scala
import org.yaml.snakeyaml.Yaml
class JavaMapIteratorWrapper[K,V] (map: java.util.Map[K,V]) {
def foreach (f: Tuple2 [K, V] => Unit): Unit = {
val iter = map.entrySet.iterator
while (iter.hasNext) {
val entry = iter.next
f (entry.getKey, entry.getValue)
}
}
}
implicit def foreachJavaMap[K,V] (map: java.util.Map[K,V]): JavaMapIteratorWrapper[K,V] = new JavaMapIteratorWrapper[K,V](map)
val yaml = new Yaml;
(yaml load (io.Source.fromFile(argv(0)).mkString)) match {
case map: java.util.Map [_, _] => {
for (entry <- map) {
entry match {
case ("id", id: String) => System.out.println ("ID is " + id)
case (n: String, v: String) => System.out.println (n + " = " + v)
}
}
}
}
$ scala -unchecked -classpath jar/snakeyaml-1.7.jar ~/tmp/so1.scala eg/default.yaml
(program output as expected)
我想将循环提取到它自己的函数中。所以我尝试这样做。
$ cat ~/tmp/so2.scala
import org.yaml.snakeyaml.Yaml
class JavaMapIteratorWrapper[K,V] (map: java.util.Map[K,V]) {
def foreach (f: Tuple2 [K, V] => Unit): Unit = {
val iter = map.entrySet.iterator
while (iter.hasNext) {
val entry = iter.next
f (entry.getKey, entry.getValue)
}
}
}
implicit def foreachJavaMap[K,V] (map: java.util.Map[K,V]): JavaMapIteratorWrapper[K,V] = new JavaMapIteratorWrapper[K,V](map)
val processMap = (map: java.util.Map [_, _]) => {
for (entry <- map) { // line 16
entry match {
case ("id", id: String) => System.out.println ("ID is " + id)
case (n: String, v: String) => System.out.println (n + " = " + v)
}
}
}
val yaml = new Yaml;
(yaml load (io.Source.fromFile(argv(0)).mkString)) match {
case map: java.util.Map [_, _] => processMap (map)
}
$ scala -unchecked -classpath jar/snakeyaml-1.7.jar ~/tmp/so2.scala eg/default.yaml
(fragment of so2.scala):16: error: type mismatch;
found : map.type (with underlying type java.util.Map[_, _])
required: java.util.Map[_$1,_$2] where type _$2, type _$1
for (entry <- map) {
^
one error found
!!!
discarding <script preamble>
循环位于其自己的函数中意味着它需要更具体的类型。好的。
我将尝试使用 java.util.Map [AnyRef, AnyRef]
而不是 java.util.Map [_, _]
。
$ cat ~/tmp/so3.scala
import org.yaml.snakeyaml.Yaml
class JavaMapIteratorWrapper[K,V] (map: java.util.Map[K,V]) {
def foreach (f: Tuple2 [K, V] => Unit): Unit = {
val iter = map.entrySet.iterator
while (iter.hasNext) {
val entry = iter.next
f (entry.getKey, entry.getValue)
}
}
}
implicit def foreachJavaMap[K,V] (map: java.util.Map[K,V]): JavaMapIteratorWrapper[K,V] = new JavaMapIteratorWrapper[K,V](map)
val processMap = (map: java.util.Map [AnyRef, AnyRef]) => {
for (entry <- map) {
entry match {
case ("id", id: String) => System.out.println ("ID is " + id)
case (n: String, v: String) => System.out.println (n + " = " + v)
}
}
}
val yaml = new Yaml;
(yaml load (io.Source.fromFile(argv(0)).mkString)) match {
case map: java.util.Map [AnyRef, AnyRef] => processMap (map) // line 26
}
$ scala -unchecked -classpath jar/snakeyaml-1.7.jar ~/tmp/so3.scala eg/default.yaml
(fragment of so3.scala):26: warning: non variable type-argument AnyRef in type pattern is unchecked since it is eliminated by erasure
case map: java.util.Map [AnyRef, AnyRef] => processMap (map)
^
one warning found
!!!
discarding <script preamble>
(program output as expected)
所以现在它运行了,但它给了我一个警告。我该如何消除该警告?
注意:
- org.yaml.snakeyaml.Yaml 是用 Java 编写的,因此我无法使用类型清单。 (我可以吗?)
- 我的真实程序使用了多个 Java 库,因此当我对哪些类型做出可能错误的假设时,我希望得到警告 我被给予了。但是我如何告诉编译器“是的,我已经检查过了,它是正确的,不要再警告我”?
- 我使用的是 scala 2.7.7(因为这是与 Ubuntu 一起打包的版本)。
I have a script. It runs without warnings.
$ cat ~/tmp/so1.scala
import org.yaml.snakeyaml.Yaml
class JavaMapIteratorWrapper[K,V] (map: java.util.Map[K,V]) {
def foreach (f: Tuple2 [K, V] => Unit): Unit = {
val iter = map.entrySet.iterator
while (iter.hasNext) {
val entry = iter.next
f (entry.getKey, entry.getValue)
}
}
}
implicit def foreachJavaMap[K,V] (map: java.util.Map[K,V]): JavaMapIteratorWrapper[K,V] = new JavaMapIteratorWrapper[K,V](map)
val yaml = new Yaml;
(yaml load (io.Source.fromFile(argv(0)).mkString)) match {
case map: java.util.Map [_, _] => {
for (entry <- map) {
entry match {
case ("id", id: String) => System.out.println ("ID is " + id)
case (n: String, v: String) => System.out.println (n + " = " + v)
}
}
}
}
$ scala -unchecked -classpath jar/snakeyaml-1.7.jar ~/tmp/so1.scala eg/default.yaml
(program output as expected)
I'd like to extract the loop into its own function. So I try that.
$ cat ~/tmp/so2.scala
import org.yaml.snakeyaml.Yaml
class JavaMapIteratorWrapper[K,V] (map: java.util.Map[K,V]) {
def foreach (f: Tuple2 [K, V] => Unit): Unit = {
val iter = map.entrySet.iterator
while (iter.hasNext) {
val entry = iter.next
f (entry.getKey, entry.getValue)
}
}
}
implicit def foreachJavaMap[K,V] (map: java.util.Map[K,V]): JavaMapIteratorWrapper[K,V] = new JavaMapIteratorWrapper[K,V](map)
val processMap = (map: java.util.Map [_, _]) => {
for (entry <- map) { // line 16
entry match {
case ("id", id: String) => System.out.println ("ID is " + id)
case (n: String, v: String) => System.out.println (n + " = " + v)
}
}
}
val yaml = new Yaml;
(yaml load (io.Source.fromFile(argv(0)).mkString)) match {
case map: java.util.Map [_, _] => processMap (map)
}
$ scala -unchecked -classpath jar/snakeyaml-1.7.jar ~/tmp/so2.scala eg/default.yaml
(fragment of so2.scala):16: error: type mismatch;
found : map.type (with underlying type java.util.Map[_, _])
required: java.util.Map[_$1,_$2] where type _$2, type _$1
for (entry <- map) {
^
one error found
!!!
discarding <script preamble>
The loop being in its own function means it requires a more specific type. Okay.
I'll try with java.util.Map [AnyRef, AnyRef]
instead of java.util.Map [_, _]
.
$ cat ~/tmp/so3.scala
import org.yaml.snakeyaml.Yaml
class JavaMapIteratorWrapper[K,V] (map: java.util.Map[K,V]) {
def foreach (f: Tuple2 [K, V] => Unit): Unit = {
val iter = map.entrySet.iterator
while (iter.hasNext) {
val entry = iter.next
f (entry.getKey, entry.getValue)
}
}
}
implicit def foreachJavaMap[K,V] (map: java.util.Map[K,V]): JavaMapIteratorWrapper[K,V] = new JavaMapIteratorWrapper[K,V](map)
val processMap = (map: java.util.Map [AnyRef, AnyRef]) => {
for (entry <- map) {
entry match {
case ("id", id: String) => System.out.println ("ID is " + id)
case (n: String, v: String) => System.out.println (n + " = " + v)
}
}
}
val yaml = new Yaml;
(yaml load (io.Source.fromFile(argv(0)).mkString)) match {
case map: java.util.Map [AnyRef, AnyRef] => processMap (map) // line 26
}
$ scala -unchecked -classpath jar/snakeyaml-1.7.jar ~/tmp/so3.scala eg/default.yaml
(fragment of so3.scala):26: warning: non variable type-argument AnyRef in type pattern is unchecked since it is eliminated by erasure
case map: java.util.Map [AnyRef, AnyRef] => processMap (map)
^
one warning found
!!!
discarding <script preamble>
(program output as expected)
So now it runs, but it gives me a warning. How do I eliminate that warning?
Notes:
- org.yaml.snakeyaml.Yaml is written in Java, so I can't use type manifests. (Can I?)
- My real program uses several Java libraries, so I want to be warned when I make possibly false assumptions about what types
I'm being given. But how do I tell the compiler "yes, I've checked this, it's correct, don't warn me about it again"? - I'm using scala 2.7.7 (because that's the version that's packaged with Ubuntu).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试首先删除自定义包装器。 (2.8.1) Scala 标准库已在
scala.collection.JavaConverters
中包含一个包装器,以便更惯用地使用 Java 集合类型。 (注意:导入时不需要scala.
前缀)我还将
processMap
设为方法而不是函数,并添加类型参数:注意倒数第二行的
asScala
方法...在处理 Java/Scala 互操作时,通常最好的做法是尽早从 Java 转换为 Scala 集合,并尽可能晚地转换回来。
You could try removing your custom wrapper to start with. The (2.8.1) Scala standard library already includes a wrapper to use Java collection types more idiomatically, in
scala.collection.JavaConverters
. (note: thescala.
prefix is not needed when importing this)I'd also make
processMap
a method instead of a function, and add type params:Note the
asScala
method on the second to last line...When dealing with Java/Scala interop, it's generally a best practice to convert from Java to Scala collections at the earliest opportunity, and to convert back as late as possible.
您必须使用 Scala 2.7.X。如果您使用 2.8.1,您的 Map[_,_] 示例可以正常工作。
如果您需要使用 2.7.X,请尝试将 processMap 值转换为方法:
def processMap[K,V] = (map: java.util.Map[K,V]) =>; {...}
这似乎适合我编译,但请注意,我使用 YAML 库“存根”了这些部分。我用过:
You must be using Scala 2.7.X. If you use 2.8.1, your example with Map[_,_] works fine.
If you need to use 2.7.X, try converting your processMap value into a method:
def processMap[K,V] = (map: java.util.Map[K,V]) => {...}
That seemed to compile for me, but note that I "stubbed" the parts using the YAML library. I used: