Scala通用函数值(匿名函数) - 缺少参数类型(错误)

时间:2010-03-25 15:52:44

标签: function scala generics anonymous-function

我是Scala的新手( Scala代码运行版本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))

}

1 个答案:

答案 0 :(得分: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))
}

如果你理解它的工作正常的原因是curried方法实际上是接收第一个参数列表并返回需要其他(或其他)参数列表的函数的方法。因此,可以在第一个参数列表中确定重载,因此第二个参数列表可以利用推断类型。