2011-11-04 3 views
1

폴더를 잡고 파일 이름 (문자열)을 사용하여 파일을 가져 오는 일종의 편리한 클래스를 만들려고했습니다. 이 작품은 예상대로 하나 이해할 수없는 부분은지도 부분 Map(folder.listFiles map {file => file.getName -> file}:_*)입니다.지도와 스칼라로 이해하기 어려움

내가 어떤 유형의 호환되지 않는 종류를 방지하기 위해 거기에 :_*하지만 나는 그것이 정말로 무엇을하는지 모른다. 또한, _*은 무엇이며 대체 할 수있는 것은 무엇입니까?

감사

class FolderAsMap (val folderName:String){ 
    val folder = new File(folderName) 
    private val filesAsMap: Map[String, File] = Map(folder.listFiles map 
              {file => file.getName -> file}:_*) 

    def get(fileName:String): Option[File] = { 
    filesAsMap.get(fileName) 
    } 
} 

답변

8

을 : _ * 맞습니다. 또는, toMap를 사용할 수 있습니다 def apply [A, B] (elems: (A, B)*): Map[A, B] :

folder.listFiles map {file => file.getName -> file}.toMap 

Map(...) 객체 Map의 방법 apply입니다. 반복 매개 변수가 있습니다. 여러 매개 변수를 사용하여 호출해야합니다. : _ *는 모든 매개 변수를 하나의 Seq 인수로 전달한다는 신호로 사용됩니다.

모호성을 방지합니다. java에서 (동등한 varargs가 Seqs 대신 배열 인 경우) f(Object... args) 메서드를 호출하고 f(someArray)으로 호출하면 args에 단 하나의 항목 만 있고 someArray가 있음을 의미 할 수 있습니다 (따라서 f는 하나의 요소 인 someArray) 또는 args는 someArray이고 f는 someArray을 직접받습니다. Java는 두 번째 버전을 선택합니다. 스칼라에서는 Array보다는 더 풍부한 형식 시스템과 Seq이 있는데, 모호성이 훨씬 더 자주 발생할 수 있습니다. 규칙은 다음과 같이 항상 모든 인수를 하나씩 전달할 때 _ _를 사용해야한다는 규칙입니다. 실제 모호성이 언제 있을지 알려주는 복잡한 규칙보다는 여기에 있습니다.

+0

글쎄, 자바 부분에 대해서는 잘 모르겠다. 하지만 당신의 설명에 따르면, * python f (list *)에서 *를 사용하는 함수를 호출하는 것과 비슷합니다. –

+1

@Tg. 예, 당신은 이런 식으로 생각할 수 있습니다. – Debilski

2

_* 컴파일러가 대신 하나 개의 인수로 모두의 Map에 대한 자신의 인수로 folder.listFiles map { file => file.getName -> file}의 각 요소를 전달한다. 이 경우


map 함수 Array (folder.listFiles 때문에 반환하는 형태)를 생성한다. 따라서 작성한 경우 :

val files = folder.listFiles map { file => file.getName -> file } 

... 반환되는 유형은 Array[(String, File)]입니다. Map이 변환하려면 (@didierd 쓴처럼 또는 사용하는 방법 toMap)을 _*를 사용하여 맵 생성자에 의해 files 하나를 통과해야합니다

val filesAsMap = Map(files : _*)