这是关于Scala函数中的句法糖的问题,可以找到类似的讨论here和here。这两个答案都给出了很好的见解,但我仍然无法理解我的头脑。
也就是说,我无法理解功能如何运作?
特色功能(见下面的代码):
让我们看一个例子,
object devScript extends App {
type Set = Int => Boolean
def contains(s: Set, elem: Int): Boolean = s(elem)
def singletonSet1(elem: Int): Set = (x: Int) => x == elem
def singletonSet2(elem: Int): Set = Set(elem)
println(contains(singletonSet1(5), 5))
println(contains(singletonSet2(5), 5))
}
返回:
true
true
singletonSet1
和singletonSet2
给出了相同的结果,那么它们只是两个表达相同但不同形式的函数吗?而且,在没有明确定义布尔子句的情况下,函数如何返回true
/ false
?
答案 0 :(得分:2)
我认为这个例子有点令人困惑,因为范围内有Set
的两个定义。您可以定义自己的类型别名Set
,其类型为Int
并返回Boolean
:Int => Boolean
的函数。另一方面,您在范围内的Scala集合中也有Set
,其apply
函数的类型也相同:Int => Boolean
。我们来看看REPL中的这些类型:
scala> singletonSet1 _
res1: Int => Set = $$Lambda$1261/1618596377@4ed90b04
scala> singletonSet2 _
res2: Int => Set = $$Lambda$1262/224661478@14f08a97
scala> Set(1).apply _
res3: Int => Boolean = $$Lambda$1352/273821181@17d6b6e
// same as apply above
scala> Set(1)(_)
res4: Int => Boolean = $$Lambda$1377/1981148063@4ebe0e3f
scala> singletonSet1(1)
res5: Set = $$Lambda$1230/593573468@7574d30b
scala> singletonSet1(1)(1)
res6: Boolean = true
// or similarly:
scala> singletonSet2(1)(1)
res7: Boolean = true
正如您所看到的apply
,也写为()
符合您需要从singletonSet[1|2]
函数返回的类型。
你是对的,它们都可以用作以不同形式实现的函数:使用singletonSet1
的闭包和在Set
情况下使用常规Scala singletonSet2
。
请注意singletonSet[1|2]
不会返回布尔值,如果您给它Boolean
,它会返回一个返回Int
的函数。还有一个层次的间接涉及。如果您完全写出这些函数的类型,它将如下所示:Int => Int => Boolean
或等效:Int => Set
。
巧合的是,我写了一篇博文,试图解释这是如何运作的。你可以在这里查看:http://izmailoff.github.io/programming%20languages/functional%20programming/functional_sets。希望它足够清楚。
答案 1 :(得分:2)
Set(elem)
引用scala.collection.Set
的伴随对象,它是值,因此不会被type
定义{{1 }}
只需运行它即可查看:
Set
它会打印object devScript extends App {
type Set = Int => Boolean
def contains(s: Set, elem: Int): Boolean = s(elem)
def singletonSet1(elem: Int): Set = (x: Int) => x == elem
def singletonSet2(elem: Int): Set = Set(elem)
println(contains(singletonSet1(5), 5))
println(contains(singletonSet2(5), 5))
println(singletonSet2(42).getClass)
}
,true
,true
,
而不是像class scala.collection.immutable.Set$Set1
这样的东西,正如你所期望的那样。
更令人困惑的是,Int => Boolean
也有效,因为scala的标准集contains(singletoSet2(5), 5)
也实现了Set[A]
,可以看出{ {3}}