Принцип замещения Лискова гласит, что
если
S
является подтипомT
, тогда объекты типаT
могут быть заменены объектами типаS
без изменения каких-либо желаемых свойств этой программы.
Однако в Scala есть PartialFunction
, который применим / определен не во всех случаях.
trait Function1 {
def apply(x: A): R
}
trait PartialFunction extends Function1 {
def apply(x: A): R
def isDefinedAt(x: A): Boolean
}
Если вы примените PartialFunction
к неопределенному значению, вы получите исключение.
Удобный способ создать PartialFunction
в scala - использовать сопоставление с образцом. При этом вы получите MatchError
для неопределенных значений.
val fn:Function1[String, Int] = s => s.length
val pf:PartialFunction[String, Int] = {
case "one" => 3
}
def program(f:Function1[String, Int], s:String):(Boolean, Int) = (
f.isInstanceOf[Function1[String, Int]], f(s)
)
program(fn, "one") == program(pf, "one")
program(fn, "two") == program(pf, "two")
fn: String => Int = ‹function1>
pf: PartialFunction [String, Int] = ‹function1>
программа: программа [] (val f: String => Int, val s: String) => (Boolean, Int)
res0: Boolean = true
scala.MatchError: два (класса java.lang.String)
в scala.PartialFunction $$ anon $ 1.apply (delme.sc:249)
в scala.PartialFunction $$ anon $ 1.apply (delme.sc:247)
в ...
И fn
, и pf
являются подтипами Function1
, но я не могу заменить fn
на pf
без изменения моего program
. Так что на мой взгляд это нарушение LSP.
Что вы думаете ?
Function1
, который просто генерирует исключения для всех входных данных, кроме"one"
. Ваш аргумент в пользу нарушения LSP состоит в том, что генерирование исключения может быть нежелательным изменением, ноFunction1
все еще может иметь входы, которые генерируют исключения. напримерBigDecimal("abc")
. Основное различие междуPartialFunction
иFunction1
заключается в том, что у вас есть встроенный способ проверки того, определены ли элементы первыми. - person Michael Zajac   schedule 03.11.2016