0
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

4 回答 4

3

我不确定是否进一步分解。这是我能想到的——我希望你明白,或者其他人感觉比我聪明。

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

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

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

编辑

我不确定你所说的形式参数是什么意思。该方法first没有值参数,只有类型参数。试图将值参数传递给它会是一个语法错误。

于 2012-05-27T07:09:55.420 回答
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,_)。)

于 2012-05-27T11:29:29.547 回答
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
于 2012-05-27T08:54:04.213 回答
0

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

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

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

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

我首先要问的问题之一是方法的形式参数是什么。

参见维基百科>参数#计算机科学

于 2012-05-27T18:21:25.473 回答