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);
}