Szukaj…


Składnia

  • for {clauses} body
  • for {clause} fed body
  • dla treści (klauzul)
  • dla (klauzul) fedruj treść

Parametry

Parametr Detale
dla Wymagane słowo kluczowe do użycia pętli for / zrozumienia
klauzule Iteracja i filtry, nad którymi działa for.
wydajność Użyj tego, jeśli chcesz utworzyć lub „wydać” kolekcję. Korzystanie yield powoduje typ powrotnego ruchu for być zbiorem zamiast Unit .
ciało Treść wyrażenia, wykonywana przy każdej iteracji.

Basic For Loop

for (x <- 1 to 10)
  println("Iteration number " + x)

To pokazuje iterację zmiennej x od 1 do 10 i zrobienie czegoś z tą wartością. Zwracanym typem tego for zrozumienia jest Unit .

Podstawowy do zrozumienia

Pokazuje to filtr w pętli for i wykorzystanie yield do stworzenia „zrozumienia sekwencji”:

for ( x <- 1 to 10 if x % 2 == 0)
  yield x

Dane wyjściowe są następujące:

scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)

Zrozumienie jest przydatne, gdy trzeba utworzyć nową kolekcję na podstawie iteracji i jej filtrów.

Nested For Loop

To pokazuje, jak można iterować wiele zmiennych:

for {
  x <- 1 to 2
  y <- 'a' to 'd'
} println("(" + x + "," + y + ")")

(Należy pamiętać, że to tutaj jest metoda operator infix która zwraca zakres integracyjnego . Patrz definicja tutaj ).

To tworzy wynik:

(1,a)
(1,b)
(1,c)
(1,d)
(2,a)
(2,b)
(2,c)
(2,d)

Zauważ, że jest to równoważne wyrażenie, które używa nawiasów zamiast nawiasów:

for (
  x <- 1 to 2
  y <- 'a' to 'd'
) println("(" + x + "," + y + ")")

Aby zebrać wszystkie kombinacje w jeden wektor, możemy yield wynik i ustawić go na val :

val a = for {
  x <- 1 to 2
  y <- 'a' to 'd'
} yield "(%s,%s)".format(x, y)
// a: scala.collection.immutable.IndexedSeq[String] = Vector((1,a), (1,b), (1,c), (1,d), (2,a), (2,b), (2,c), (2,d))

Monadyczny dla zrozumienia

Jeśli masz kilka obiektów typów monadycznych , możemy osiągnąć kombinacje wartości za pomocą „do zrozumienia”:

for {
   x <- Option(1)
   y <- Option("b")
   z <- List(3, 4)
} {
    // Now we can use the x, y, z variables
    println(x, y, z)
    x  // the last expression is *not* the output of the block in this case!
}

// This prints
// (1, "b", 3)
// (1, "b", 4)

Typ zwracany tego bloku to Unit .

Jeśli obiekty są tego samego typu monadycznej M (np Option ), a następnie za pomocą yield powróci obiekt typu M , a nie z Unit .

val a = for {
   x <- Option(1)
   y <- Option("b")
} yield {
    // Now we can use the x, y variables
    println(x, y)
    // whatever is at the end of the block is the output
    (7 * x, y)
}

// This prints:
// (1, "b")
// The val `a` is set:
// a: Option[(Int, String)] = Some((7,b))

Zauważ, że słowa kluczowego yield nie można użyć w oryginalnym przykładzie, w którym występuje kombinacja typów monadycznych ( Option i List ). Próba zrobienia tego spowoduje błąd niedopasowania typu kompilacji.

Iteruj przez kolekcje za pomocą pętli For

To pokazuje, jak wydrukować każdy element mapy

val map = Map(1 -> "a", 2 -> "b")
for (number <- map) println(number) // prints (1,a), (2,b)
for ((key, value) <- map) println(value) // prints a, b

To pokazuje, jak wydrukować każdy element listy

val list = List(1,2,3)
for(number <- list) println(number) // prints 1, 2, 3

Desugaring dla zrozumienia

for pojęcia w Scali to tylko cukier składniowy . Te withFilter są realizowane za pomocą withFilter , foreach , flatMap i map ich typów tematycznych. Z tego powodu tylko typy, dla których zdefiniowano te metody, mogą być wykorzystane for zrozumienia.

A for zrozumienia następującej postaci, z wzorami pN , generatorami gN i warunkami cN :

for(p0 <- x0 if g0; p1 <- g1 if c1) { ??? }

... usunie cukier z zagnieżdżonych wywołań za pomocą funkcji withFilter i foreach :

g0.withFilter({ case p0 => c0  case _ => false }).foreach({
  case p0 => g1.withFilter({ case p1 => c1  case _ => false }).foreach({
    case p1 => ???
  })
})

Natomiast wyrażenie for / yield następującej formy:

for(p0 <- g0 if c0; p1 <- g1 if c1) yield ???

... usunie cukier z zagnieżdżonych połączeń za pomocą withFilter i flatMap lub map :

g0.withFilter({ case p0 => c0  case _ => false }).flatMap({
  case p0 => g1.withFilter({ case p1 => c1  case _ => false }).map({
    case p1 => ???
  })
})

(Zauważ, że map jest używana w najgłębszym rozumieniu, a flatMap jest używany w każdym zewnętrznym rozumieniu).

for zrozumienia można zastosować dowolny typ implementujący metody wymagane przez odwodnioną reprezentację. Nie ma żadnych ograniczeń dotyczących typów zwracanych tych metod, o ile można je skomponować.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow