如何使用以下f
函数之一打印“我不偏袒”,为什么下面的代码会打印“我偏爱”?也许有一些与函数相关的通用规则(可能是arity 0)在scala中产生了部分函数和名称重载?
object T1 extends App{
case class C()
def f: PartialFunction[C, Unit] = { case c:C ⇒ println( "I'm partial") }
def f(c: C): Unit = { println("I'm not partial") }
(f:C ⇒ Unit)(C()) // Why this is printing "I'm partial"?
}
答案 0 :(得分:4)
表达式不是应用程序。将x的定义与模糊调用进行比较:
scala> :pa
// Entering paste mode (ctrl-D to finish)
object T1 extends App{
case class C()
def f: PartialFunction[C, Unit] = { case c:C ⇒ println( "I'm partial") }
def f(c: C): Unit = { println("I'm not partial") }
(f:C ⇒ Unit)(C()) // Why this is printing "I'm partial"?
}
// Exiting paste mode, now interpreting.
defined object T1
scala> T1 main null
I'm partial
scala> import T1._
import T1._
scala> val x: C => Unit = f
x: T1.C => Unit = <function1>
scala> f(C())
<console>:12: error: ambiguous reference to overloaded definition,
both method f in object T1 of type (c: T1.C)Unit
and method f in object T1 of type => PartialFunction[T1.C,Unit]
match argument types (T1.C)
f(C())
^
scala> x(C())
I'm partial
The spec表示f
与f(...)
(第3章)具体相同,但不相反(通过项目符号1)。
应用程序的parens意味着您要比较两个看起来像f(...)
的东西。
如果这有帮助,通常的优先顺序排列方式:
scala> trait Helper { def f: PartialFunction[C, Unit] = { case c:C ⇒ println( "I'm partial") } }
defined trait Helper
scala> :pa
// Entering paste mode (ctrl-D to finish)
object T extends Helper {
def f(c: C): Unit = { println("I'm not partial") }
}
// Exiting paste mode, now interpreting.
defined object T
scala> T f new C
I'm not partial
您可以编写其他API,但不能以正常方式调用:
scala> trait X { def f(i: => Int) = i }
defined trait X
scala> trait Y { def f(i: Int) = 2 * i }
defined trait Y
scala> class Z extends X with Y
defined class Z
scala> new Z().f(42)
res5: Int = 84
scala> typeOf[Z].members filter (_.name.toString == "f")
res7: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(method f, method f)
scala> (new Z(): X).f(42)
res8: Int = 42
或者,无法在此处调用其他函数:
scala> class YY extends Y { def f(i: => Int) = i }
defined class YY
scala> new YY().f(42)
<console>:20: error: ambiguous reference to overloaded definition,
both method f in class YY of type (i: => Int)Int
and method f in trait Y of type (i: Int)Int
match argument types (Int)
new YY().f(42)
^
scala> (new YY(): Y).f(42)
res15: Int = 84