7C00.ME/houmu 2013-06-05

Scala应避免按需类型导入

今天在编译一个Scala程序的时候报出一个奇异的错误。

/path/to/src.scala:xx:error: class file needed by SparkContext is missing.
reference value io of package org.apache.hadoop refers to nonexisting symbol.
	val x = args(2).toInt
			        ^
/path/to/src.scala:xx:error:
reference value io of package org.apache.hadoop refers to nonexisting symbol.
	sparkContext.parallelize(1  to s, s)
								^ 这个错误让人很费解,我在代码中没有用到Hadoop,而包含SparkContext类的jar也在CLASSPATH上。错误指向的两个位置也看不出问题来,但是一旦我把比如args(2).toInt这行给注释了,对应的那个编译错误就消失了。这句话有什么错误呢?args(2)不就是个String么,toInt的使用也没错啊。而那个 1 to s(s是个整数值)就更没什么问题了。我在Scala REPL中实验了类似的语句,都是正常运行的。那么错误出在什么地方呢?

忽然间,我想到Scala是自动做类型推演的,1 to s的to错了,难道没有把1识别成Int类型?莫非是推演出了org.apache.hadoop包中的某个类?我也不确定是不是这个原因,但是看到代码开头这么写

import scala.math.random
import scala._
import SparkContext._
import java.io._
import spark.rdd.MappedRDD
...

觉得有可能,试试改成了这样。

import spark.SparkContext
import java.io.BufferedInputStream
import java.io.FileInputStream
...

重新编译,错误消失了。第一段代码虽然是Scala语法允许,但是存在了一些风险。所以以后还是避免按需类型引入。