В основе различие заключается в том, что isDefinedAt в частичной функции не определяется, как можно было бы ожидать в версии с использованием метода PartialFunction.apply. Именно поэтому этот метод теперь устарел, PartialFunction.apply предназначен для преобразования всей функции в частичную функцию с isDefinedAt, всегда возвращающей true, что означает, что он будет считать, что она определена для 3 в вашем примере, и попытаться применить функцию вместо возврата к четной функции, которую вы предоставили в качестве альтернативы.
Это поднимает общую больную точку в сообществе относительно полных функций против частичных функций. PartialFunction является подтипом Function, я предполагаю, что в смысле разработки ОО это функция с дополнительным методом (isDefinedAt), который сообщает вам, определена ли функция для определенного значения. Многие считают, что это ошибка, так как в смысле Лискова, Function должна быть подтипом PartialFunction, потому что вы можете использовать функцию везде, где ожидается PartialFunction, но если вы используете PartialFunction там, где ожидается функция, она скомпилируется, то может произойти сбой во время выполнения. Мне кажется, это потому, что Function может иметь неявный isDefinedAt, который всегда возвращает true, что позволит вам исправить отношение и сделать Function подтипом PartialFunction. Это происходит в PartialFunction.apply, которая ожидает итоговую функцию и из-за этого ожидания определяет, что isDefinedAt всегда возвращает true, но не может обеспечить это ожидание, поэтому, если вы вызываете PartialFunction.apply (somePartialFunction), происходят плохие вещи, которые программисты не ожидают.
B):PartialFunction[A,B]" rel="noreferrer"> PartialFunction.apply Scaladoc
PartialFunction[Int, String]{...} is syntactic sugar for
PartialFunction[Int, String].apply({...})
Чтобы минимизировать:
val even: PartialFunction[Int, String] = PartialFunction[Int, String]{
case i if i % 2 == 0 => i + " is even"
}
val isEven: PartialFunction[Int, String] = {
case i if i % 2 == 0 => i + " is even"
}
println(even.isDefinedAt(3)) //true
println(isEven.isDefinedAt(3)) //false