2016-02-07 107 views
1

我想要一個功能readFile,它需要輸入一個變量file。文件可以是stringjava.io.File。假設有一個功能readJavaFile接受java.io.File作爲輸入。scala模式匹配

我想要做的事,如:

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

什麼是實現這個正確的方式?我看到類似的問題,但他們指的是更復雜的情況。

編輯: 恐怕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 { 
      ^

回答

4

我想你想是這樣的:

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

無論是兩個集的集合:左,右。 您也可以使用折解決這個問題:

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

Ta。我會刪除我的評論(這在一分鐘內) –

1

你的模式做什麼,是,比賽中的「文件」的類型。但這是真的。你應該做的,而不是爲符合您所擁有的那種非此即彼的實例:

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

你有什麼工作,如果你的參數類型是任何,但你不希望這樣做。 (或者文件和字符串的聯合,這與Either和Scala沒有的東西不一樣)(還))

5

聽起來像是一個重載給我的完美情況。

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

除非你已經有過在Either的字符串或文件,將它們放入一個Either只是爲了讓他們再次出來似乎比需要更多的複雜。

+0

這似乎是最好的解決方案。 readJavaFile函數也有其他參數。在這種情況下,這也被認爲是好的嗎?我會有這樣的:'def readFile(s:String,c:C,d:D)= ..'和'def readFile(f:File,c:C,d:D)' – Donbeo

+0

'c'和'd'有默認值 – Donbeo

+0

對我來說看起來不錯。你想如何處理默認值?你想要readFile也有默認值? –