Scala изисква променливите на шаблона да са линейни, т.е. променлива може да не се среща повече от веднъж в шаблон. Следователно, този пример не компилира:
def tupleTest(tuple: (Int, Int)) = tuple match {
case (a, a) => a
case _ => -1
}
Но можете да използвате две променливи на шаблон и предпазител, за да проверите равенството вместо:
def tupleTest(tuple: (Int, Int)) = tuple match {
case (a, b) if a == b => a
case _ => -1
}
Така че защо Scala изисква променливите на модела да бъдат линейни? Има ли случаи, които не могат да се трансформират така?
Лесно е да преобразувате първия пример във втория (Скала до Скала). От всички събития на променлива v
в шаблона вземете изразите, които първо се оценяват и го присвойте на променливата v
, Във всеки друг случай въведете нова променлива с име, което не се използва в текущия обхват. За всяка от тези променливи v"
добавете пазач v == v"
, По същия начин би тръгнал един програмист (=> същата ефективност). Има ли някакъв проблем с този подход? Бих искал да видя пример, който не може да се трансформира така.
Отговори:
0 за отговор № 1защото case (a, b)
е основно приписване val a
да се _._1
и val b
да се _._2
(поне можете да го видите така). В случай на case (a, a)
, не можете да зададете val a
към двете _._1
и _._2
.
Всъщност нещото, което искате да направите, щеше да изглежда
case (a, `a`) => ???
като scala използва backtick, за да съответства на идентификатор. Но за съжаление това все още не работи като видимост на a
се дава само след =>
(би било забавно все пак, аз също мразя писането case (a, b) if a = b =>
). И причината за това вероятно е само защото е по-трудно да се напише компилатор, който поддържа това