Weź następującą funkcję:
def fMatch(s: String) = {
s match {
case "a" => println("It was a")
case _ => println("It was something else")
}
}
Ten wzór ładnie pasuje:
scala> fMatch("a")
It was a
scala> fMatch("b")
It was something else
Chciałbym móc wykonać następujące czynności:
def mMatch(s: String) = {
val target: String = "a"
s match {
case target => println("It was" + target)
case _ => println("It was something else")
}
}
Powoduje to następujący błąd:
fMatch: (s: String)Unit
<console>:12: error: unreachable code
case _ => println("It was something else")
Wydaje mi się, że dzieje się tak, ponieważ uważa, że cel jest w rzeczywistości nazwą, którą chcesz przypisać do tego, co jest na wejściu. Dwa pytania:
Dlaczego to zachowanie? Czy nie można po prostu poszukać istniejących zmiennych w zakresie, które mają odpowiedni typ i użyć ich najpierw, a jeśli nie zostaną znalezione, potraktować cel jako nazwę do dopasowania do wzorca?
Czy istnieje obejście tego problemu? Jakiś sposób na dopasowanie wzorca do zmiennych? Ostatecznie można by użyć dużego stwierdzenia if, ale opakowanie zapałek jest bardziej eleganckie.
scala
pattern-matching
match
Henry Henrinson
źródło
źródło
Odpowiedzi:
To, czego szukasz, to stabilny identyfikator . W Scali muszą one zaczynać się od dużej litery lub być otoczone grawitacjami.
Oba rozwiązania byłyby rozwiązaniem Twojego problemu:
Aby uniknąć przypadkowego odwoływania się do zmiennych, które już istniały w obejmującym zakresie, myślę, że ma sens, aby domyślnym zachowaniem wzorce z małych liter były zmienne, a nie stabilne identyfikatory. Tylko wtedy, gdy widzisz coś zaczynającego się od dużej litery lub od tyłu, musisz mieć świadomość, że pochodzi z otaczającego zakresu.
źródło
target
jest to wartość (val
), a nie zmienna (var
). Nie działa ze zmiennymi.Nil
, które mi zakład jest prawdziwy powód.this
stabilnego identyfikatora do dopasowania wzorca do niego, jedynym sposobem wydaje się być użycie takiego zabezpieczenia równościcase x if x == this =>
. Prawdopodobnie ograniczenie składniowe, w przeciwnym razie powinno działać semantycznie przynajmniej w ciąguobject
s.