用方法创建函数?细节说明?

时间:2012-05-27 06:58:27

标签: scala

def first[A] :Tuple2[A,_] => A  = ( pair :Tuple2[A,_] ) => pair._1
val name = first( ("Anna", 23) )

“如果你仔细看看第2行,你在这里看到的是一个方法调用,它返回一个新创建的Tuple2类型的函数[String,Any] => String(因为编译器启动并推断出所需的虽然整个表达式看起来像普通的方法调用,但它实际上是一个方法调用(对于没有任何参数的工厂方法)和之后跟随的函数调用。“ - 这是对它的解释上面的代码。

我无法推断上述过程的第一步(创建函数对象的过程)。有人可以明确地写出“人工编译”程序吗?

编辑:我认为第2行的完全扩展逻辑应该是以下两行

val firstAsFunc= first[String]; 
val name = firstAsFunc(("Anna", 23))

4 个答案:

答案 0 :(得分:3)

我不确定是否会进一步分解。这就是我能想到的 - 我希望你能得到它,或者其他人感觉比我更聪明。

scala> val func = first[String] // method call
func: Tuple2[String, _] => String = <function1>

scala> val name = func( ("Anna", 23) )
name: String = Anna

上面的问题是func实际上是一个getter - 一个方法调用本身 - 所以我几乎没有改变任何东西。

修改

我不确定 formal 参数的含义。方法first没有值参数,只是类型参数。尝试将值参数传递给它将是一个语法错误。

答案 1 :(得分:3)

当你说

(pair: Tuple2[A,_]) => pair._1

编译器决定你实际上在说

new Function1[Tuple2[A,_], A] {
  def apply(pair: Tuple2[A,_]) = pair._1
}

也就是说,first方法使用名为Function1的方法创建一个新对象(类型为apply),当您说first(...)时,该方法会被透明地调用。 (如果你写了first.apply(...),你会得到同样的东西。)

(注意:Tuple2[A,_]本身可以缩写为(A,_)。)

答案 2 :(得分:1)

我不是100%确定我理解你要问的过程中的哪一点 - 你是在询问函数对象是什么?我会假设它是: - )

来回答这个问题

函数对象是从FunctionN(Function0Function1等)特征之一派生的对象,并实现apply方法。所以你的例子可以改写:

scala> def first[A]: Tuple2[A, _] => A = new Function1[Tuple2[A, _], A] { def apply(pair: Tuple2[A, _]) = pair._1 }
first: [A]=> Tuple2[A, _] => A

scala> val name = first( ("Anna", 23) )
name: java.lang.String = Anna

您可以看到函数实际上是FunctionN的一个实例,如下所示:

scala> def foo(x: Int, y: Double): String = "x = "+ x.toString +", "+ y.toString
foo: (x: Int, y: Double)String

scala> (foo _).isInstanceOf[Function2[_, _, _]]
res1: Boolean = true

答案 3 :(得分:0)

  

如果你仔细看看第2行,你在这里看到的是一个方法调用,它返回一个新创建的Tuple2[String,Any] => String类型函数

这种解释是错误的。第2行不“返回新创建的函数”。该函数在第1行创建,如Rex Kerr所述。

  

尽管整个表达式[在第2行]看起来像是一个普通的方法调用,但它实际上是一个方法调用(对于没有任何参数的工厂方法)和随后的函数调用。

我不相信这是真的;没有隐藏的工厂方法,因为已在第1行创建了Function1对象。

  

我问的其中一个问题是什么是方法的形式参数。

请参阅Wikipedia > Parameter # Computer Science