3

以下は、小規模なタスクを実行することが期待されているが、異なる方法で定義されている 2 つの部分関数です。

val pf1 : PartialFunction[String, String] = { 
  case s : String if (s != null) =>  s.toUpperCase()
}
//> pf1  : PartialFunction[String,String] = <function1>

val lift1 = pf1.lift
//> lift1  : String => Option[String] = <function1>

val d1 = lift1(null)
//> d1  : Option[String] = None

val d2 = lift1("hello world")
//> d2  : Option[String] = Some(hello world)

val pf2 = PartialFunction[String, String] { 
  case s : String if(s != null) =>  s.toUpperCase()
}
//> pf2  : PartialFunction[String,String] = <function1>

val lift2 = pf2.lift
//> lift2  : String => Option[String] = <function1>

val d3 = lift2(null)
//> scala.MatchError: null

val d4 = lift2("hii")
//> d4  : Option[String] = Some(hii)

Lift1 と Lift2 の両方の定義が同じ場合に、Lift2 に null を渡すと MatchError が返されるのはなぜですか?

4

2 に答える 2

1

Lift1 と Lift2 の両方の定義が同じ場合に、Lift2 に null を渡すと MatchError が返されるのはなぜですか?

それらは同じように定義されていません。定義する場合:

val pf1: PartialFunction[String, String] = {
  case s : String if (s != null) =>  s.toUpperCase()
}

コンパイラはPartialFunction、次のようにを作成します。

this.pf1 = ({
    new <$anon: Function1>()
  }: PartialFunction);

しかし、次pf2のように宣言すると:

val pf2 = PartialFunction[String, String] {
  case s : String if(s != null) =>  s.toUpperCase()
}

あなたは実際にコンパイラに「これを取ってFunction1に渡してくださいPartialFunction.apply。それがコンパイラがこれを行う理由です:

this.pf2 = scala.PartialFunction.apply({
    (new <$anon: Function1>(): Function1)
});

これは実際にFunction1は部分関数内にラップします。したがって、 を呼び出すとpf2.lift(null)、内部で が呼び出され、ご覧のように がFunction1発生MatchErrorします。

于 2016-03-20T08:16:02.637 に答える
1

を見るとPartialFunction.apply、期待していたものとは少し異なることがわかります。

  /** Converts ordinary function to partial one
   *  @since   2.10
   */
  def apply[A, B](f: A => B): PartialFunction[A, B] = { case x => f(x) }

したがって、通常の関数をすべてのドメインで定義されている部分関数にラップします。そしてそれが、持ち上げると例外を受け取る理由です-内部はまだ通常の持ち上げられていない部分関数であり、定義されていないためです

于 2016-03-20T07:48:42.117 に答える