Scala 任何to函数的隐式def都会将apply方法添加到类中

Scala 任何to函数的隐式def都会将apply方法添加到类中,scala,Scala,看看下面的内容,看看你是否能理解它: Welcome to Scala version 2.8.1.final (Java HotSpot(TM) Client VM, Java 1.6.0_17). Type in expressions to have them evaluated. Type :help for more information. scala> class A defined class A scala> val a = new A a: A = A@164

看看下面的内容,看看你是否能理解它:

Welcome to Scala version 2.8.1.final (Java HotSpot(TM) Client VM, Java 1.6.0_17).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class A
defined class A

scala> val a = new A
a: A = A@1643e4b

scala> a.apply("foo")
<console>:8: error: value apply is not a member of A
       a.apply("foo")
         ^
突然间,A有了一个
apply
方法,该方法接受与隐式返回的函数相同类型的参数

让我们再检查一下:

scala> class B { override def toString = "an instance of class B" }
defined class B

scala> implicit def anyToFunc(any: Any) = { x: String =>
     | println("any is " + any.toString)
     | println("x is " + x)
     | "bar" }
anyToFunc: (any: Any)(String) => java.lang.String

scala> val b = new B
b: B = an instance of class B

scala> b.apply("test")
any is an instance of class B
x is test
res8: java.lang.String = bar

这是“隐藏特征”吗?如果是,它有什么用途?

与其说它是一个隐藏的特性,不如说它是隐式定义的预期行为和
apply
方法。关键的是,
apply
方法是一种特殊的方法,当您将参数直接传递给对象时会调用它。因此,在您的示例中,当您执行以下操作时:

b.apply("Test")
这相当于
b(“测试”)
<代码>函数定义应用,这样我们就可以做一些好事,比如:

val addOne = (b : Int) => b + 1
addOne(10)

因此,当您尝试对
B
的实例调用apply时,编译器首先查看
B
是否应用了方法,然后查看
B
的超类是否应用了方法,然后查找具有方法
应用的隐式对象。这就是隐式定义的目的。由于
Function1
有一个apply方法,因此会调用隐式转换,同时也会调用函数的apply方法。

在scala中创建的任何函数都会使用apply方法转换为类。那么调用apply的简写就是省略它。
class A{
    val a = (x:String) => x * 2
}
编译此文件并查看是否创建了两个文件,
A.class
A$$anonfun$1.class
。用javap检查类文件,您将看到
Compiled from "Fun.scala"
public final class A$$anonfun$1 extends scala.runtime.AbstractFunction1 implements java.io.Serializable{
    public static final long serialVersionUID;
    public static {};
    public final java.lang.String apply(java.lang.String);
    public final java.lang.Object apply(java.lang.Object);
    public A$$anonfun$1(A);
}
重要的一行是
public final java.lang.String apply(java.lang.String)。这可以通过
a(“字符串”)
a.apply(“字符串”)
调用。


是的,您可以使用
隐式def
s将任何内容转换为函数,但这没有多大意义。它通常用于不同的情况:

您正在调用的
对类型为
A
的对象应用
<代码>A
没有
应用
方法。但是
A
可以隐式转换为
函数[String,String]
,该函数具有
apply
方法。因此,将应用隐式转换,并对转换的对象调用
apply


这个功能没有什么神奇或隐藏的地方。如果一个对象没有您正在调用的方法,但是可以隐式地转换为具有该方法的对象,那么它将被转换。这正是隐式转换的目的。

你说的“隐藏特征”到底是什么意思?若你们把任何东西转换成函数,那个么是的,它将有apply方法。你们说得对。在发布问题后思考后,我觉得这很有意义。:)在我无意中“发现”它的背景下,它似乎完全令人难以置信。
Compiled from "Fun.scala"
public final class A$$anonfun$1 extends scala.runtime.AbstractFunction1 implements java.io.Serializable{
    public static final long serialVersionUID;
    public static {};
    public final java.lang.String apply(java.lang.String);
    public final java.lang.Object apply(java.lang.Object);
    public A$$anonfun$1(A);
}