2010-03-25 105 views
9

我是新來的斯卡拉(斯卡拉代碼亞軍版本2.7.7.final),我真的不明白爲什麼它需要調用者當我們使用高階函數時提供參數類型。斯卡拉通用函數值(匿名函數) - 缺少參數類型(錯誤)

在下面的示例中,我有一個獨立的對象(Util),它具有一個功能。但是在Main塊中,調用者必須將參數類型傳遞給匿名函數。

爲什麼Scala不能從Array類型(即String)推斷出函數的類型?有沒有辦法做到這一點?

object Util { 

// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length. 
// will swap the elements from arrayOne to ArrayTwo. 
    def swap[T](arrayOne:Array[T], arrayTwo:Array[T] , f:(T,T) =>(T,T)) { 
    for(i <- 0 until (arrayOne.length min arrayTwo.length)){ 
     val (left, right) = f(arrayOne(i),arrayTwo(i)) 
     arrayOne(i) = left 
     arrayTwo(i) = right 
    } 
    } 
} 

object Main extends Application { 

    val arrayOne = Array("A","B","C") 
    val arrayTwo = Array("D","E","F") 

//If not specified the type String,the compiler throws "Missing Parameter Type" error 

Util swap(arrayOne, arrayTwo,(elem1:String,elem2:String)=>(elem2,elem1)) 

} 
+0

對我來說只有a}在Util對象中缺失。 –

+0

@Thomas它的工作原理是因爲他在函數中指定了類型。 :-) –

+0

@Daniel類型註釋是這個代碼困擾我的最後一件事。我想知道是否要解決它是不禮貌的。把注意力轉移到最後一行。 –

回答

14

它並不推斷T的類型,因爲它具有唯一通過在這一點上走會arrayOnearrayTwo。但是,Scala並未使用一個參數的類型來推斷另一個參數的類型,可能是因爲它會導致方法重載問題。然而,它的工作原理,如果你討好它:

Object Util { 

// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length. 
// will swap the elements from arrayOne to ArrayTwo. 
    def swap[T](arrayOne:Array[T], arrayTwo:Array[T])(f:(T,T) =>(T,T)) : Unit = { 
    var i = 0 
     var tuple :Tuple2[T,T] = null 
     while(i < arrayOne.length && i < arrayTwo.length){ 
     tuple =f(arrayOne(i),arrayTwo(i)) 
     arrayOne(i) = tuple._1 
     arrayTwo(i) = tuple._2 
     i+=1 
     } 
     } 
} 

object Main extends Application { 

    // val works fine below -- the object is mutable 
    val arrayOne = Array("A","B","C") 
    val arrayTwo = Array("D","E","F") 

    (Util swap(arrayOne, arrayTwo))((elem1,elem2)=>(elem2,elem1)) 
    // The weird parenthesis is caused by mixing operator notation and currying 
    // One could also write it like this: 
    // Util.swap(arrayOne, arrayTwo)((elem1,elem2)=>(elem2,elem1)) 
} 

之所以它,如果你咖喱它是一個令行禁止方法實際上是接收的第一個參數列表,並返回需要其他的功能的方法工作正常(或其他)參數列表。因此,可以在第一個參數列表中決定重載,因此第二個參數列表可以利用推斷的類型。

+0

謝謝丹尼爾..真的很享受你的回答! – CHAPa