scala模式与之匹配

时间:2016-02-07 15:00:57

标签: java scala

我想要一个函数readFile,它将变量file作为输入。文件可以是stringjava.io.File。假设有一个函数readJavaFile接受java.io.File作为输入。

我想做类似的事情:

def readFile(file:Either[String, File]) = {
   file match {
     case s:String => readJavaFile(new File(s))
     case s:File => readJavaFile(s)
   }
}

实施此方法的正确方法是什么?我在SO上看到了类似的问题,但他们指的是更复杂的情况。

编辑: 我担心Either不是可以遵循的方式。我希望能够将该函数称为: readFile(s)其中s是字符串,readFile(f)其中fFile

编辑: 这是我的真实代码:

def csvread(file: File,
             separator: Char=',',
             quote: Char='"',
             escape: Char='\\',
             skipLines: Int = 0): DenseMatrix[Double] = {
    val input = new FileReader(file)
    var mat = CSVReader.read(input, separator, quote, escape, skipLines)
    mat = mat.takeWhile(line => line.length != 0 && line.head.nonEmpty) // empty lines at the end
    input.close()
    if(mat.length == 0) {
      DenseMatrix.zeros[Double](0,0)
    } else {
      DenseMatrix.tabulate(mat.length,mat.head.length)((i,j)=>mat(i)(j).toDouble)
    }
  }

  def csvread(file: String,
              separator: Char=',',
              quote: Char='"',
              escape: Char='\\',
              skipLines: Int = 0): DenseMatrix[Double] = csvread(new File(file), separator, quote, escape, skipLines)

我想把它称为:

package breeze.linalg

/**
  * Created by donbeo on 07/02/16.
  */

import org.scalatest._
import org.scalatest.junit._
import org.scalatest.prop._
import org.junit.runner.RunWith
import breeze.linalg.csvread
import java.io.File

@RunWith(classOf[JUnitRunner])
class ReadCsvTest extends FunSuite with Checkers{

  test("Try readcsv") {
    val f = csvread(new File("/Users/donbeo/Documents/datasets/glass.csv"))
    val v = csvread("/Users/donbeo/Documents/datasets/glass.csv")

  }

}

但我收到并收到错误:

Error:(41, 16) in package object linalg, multiple overloaded alternatives of method csvread define default arguments.
package object linalg {
               ^

3 个答案:

答案 0 :(得分:5)

听起来像是对我来说超载的完美案例。

 def readFile(s:String) = readJavaFile(new File(s))
 def readFile(f:File) = readJavaFile(f)

除非您已经在Either中使用了字符串或文件,否则将它们放入Either只是为了让它们再次出现似乎比需要的更复杂。

答案 1 :(得分:4)

我想你想要这样的东西:

  def readFile(file:Either[String, File]) = {
    file match {
      case Left(s) => readJavaFile(new File(s))
      case Right(s) => readJavaFile(s)
    }
  }

要么是两个集合的集合:左和右。 你也可以使用fold来解决它:

def readFile(file: Either[String, File]): File = 
  readJavaFile(file.fold(new File(_), identity))

答案 2 :(得分:1)

您的模式所做的是,与“文件”的类型相匹配。但那是真的要么。你应该做的是匹配你所拥有的任何一个实例:

file match {
  case Left(s) => readJavaFile(new File(s))
  case Right(s) => readJavaFile(s)
}

如果您的参数类型为Any,但您不希望这样做,那么您将使用什么。 (或者文件和字符串的联合,这与Either和Scala没有的东西(还)不同)