programing

스칼라의 foreach 대 표현식

procenter 2021. 1. 14. 23:20
반응형

스칼라의 foreach 대 표현식


저는 Programming in Scala를 통해 작업하고 있습니다. Python의 관점에서보고 싶은 유혹이 있지만 "Python in Scala"를 프로그래밍하고 싶지는 않습니다.

제어 흐름이 진행되는 한 무엇을해야할지 잘 모르겠습니다. 파이썬에서 우리는 for x in some_iterable죽을 까지 사용 하고 사랑합니다. Odersky가 Java for 루프와 구별하기 위해 for expression을 호출하는 매우 유사한 구조가 Scala에 존재 합니다. 또한 Scala에는 foreach반복 가능한 데이터 유형에 대한 속성이 있습니다 (속성 일 것이라고 생각합니다. Scala에 대해 제대로 이름을 지정할 수는 없습니다). foreach그래도 컨테이너의 각 항목에 대해 하나의 함수를 호출하는 것보다 훨씬 더 많은 작업을 수행 할 수있는 것 같지 않습니다 .

이로 인해 몇 가지 질문이 남습니다. 첫째, for 표현식이 Python 에서처럼 Scala에서 중요 / 많이 사용되는 구조이고, 둘째, foreachfor 표현식 대신 언제 사용해야합니까 (컨테이너의 각 항목에 대해 함수를 호출하는 명백한 경우 제외)?

나는 내가 몹시 모호하거나 지나치게 광범위하지 않기를 바라지 만, 스칼라의 디자인 / 언어 기초의 일부를 파헤 치려고 노력하고있다 (지금까지 매우 멋져 보인다).


파이썬은 for목록 이해 및 생성기 표현식에서 사용 합니다. 사람들은 매우 스칼라 유사 for표현 :

이것은 파이썬입니다

>>> letters = ['a', 'b', 'c', 'd']
>>> ints = [0, 1, 2, 3]
>>> [l + str(i) for l in letters for i in ints if i % 2 == 0]
['a0', 'a2', 'b0', 'b2', 'c0', 'c2', 'd0', 'd2']

이것은 스칼라입니다

scala> val letters = List('a', 'b', 'c', 'd')
scala> val ints = List(0, 1, 2, 3)
scala> for (l <- letters; i <- ints if i % 2 == 0) yield l.toString + i
res0: List[java.lang.String] = List(a0, a2, b0, b2, c0, c2, d0, d2)

각 구성은 여러 생성자 / 반복자를 취하고 필터 표현식을 적용하고 결합 된 표현식을 생성 할 수 있습니다. 파이썬에서는 (expr for v1 in gen1 if expr1 for v2 in gen2 if expr2)대략 다음과 같습니다.

for v1 in gen1:
  if expr1:
    for v2 in gen2:
      if expr2:
        yield expr

스칼라 for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr에서는 대략 다음과 같습니다.

gen1.withFilter(expr1).flatMap(v1 => gen2.withFilter(expr2).map(v2 => expr))

파이썬 for x in xs구문을 좋아한다면 스칼라 for표현식 을 좋아할 것 입니다.

Scala에는 몇 가지 추가 구문 및 번역 왜곡이 있습니다. 구문 현명 for은 중괄호와 함께 사용하여 문을 별도의 줄에 넣을 수 있습니다. 값 할당을 수행 할 수도 있습니다.

val res = for {
    i <- 1 to 20; i2 = i*i
    j <- 1 to 20; j2 = j*j
    k <- 1 to 20; k2 = k*k
    if i2 + j2 == k2
  } yield (i, j, k)

또한 v1 <- gen1실제로 일치를 수행합니다 case v1 => gen1. 일치하는 항목이 없으면 해당 요소는 반복에서 무시됩니다.

scala> val list = List(Some(1), None, Some(2))
scala> for (Some(i) <- list) yield i
res2: List[Int] = List(1, 2)

나는 for언어에서 중요한 자리가 있다고 생각 합니다. 나는 당신이 읽고있는 책에 그것에 관한 전체 챕터 (23)가 있다는 사실을 알 수 있습니다!


예, 스칼라 for comprehensions (일반적으로 알려진대로)는 많이 사용되지만 실제로는 특정 메서드 조합에 대한 구문 설탕 일 뿐이며 많은 사람들이 구문 설탕을 사용하는 대신 이러한 메서드를 직접 호출하는 것을 선호합니다.

Scala의 이해도를 높이려면 이 질문을 참조하십시오 . 특히, 즉 볼 for (x <- xs) f(x)과 같은 일이다 xs.foreach(x => f(x)).

이제 foreach메서드를 많이 사용하지 않는 것 같지만 Scala 컬렉션의 거의 모든 메서드가 .NET으로 구현 (또는 구현 될 수 있음)된다는 점을 지적하겠습니다 foreach. 에 대한 문서를 참조하십시오. Traversable모든 메서드는 foreach.

Scala yield는 Python과 유사하지 않습니다 . 질문도 yield검색 할 수 있습니다.


중첩 된 반복, 필터 및 변환을 지원하므로 Scala for는 언어의 강점 중 하나이며 매우 중심적입니다. 내가 사용에 그것을 선호하는 경향이 foreach, map하고 filter.


foreach는 기능적 스타일이고 for는 명령형 스타일입니다. lisp 또는 계획을 수행 한 적이 있다면 이미 함수형 프로그래밍에 익숙합니다. 그렇지 않은 경우 처음에는 약간 혼란 스러울 수 있습니다. 가장 먼저 할 일은 foreach와 같은 것에 전달하는 익명 함수 인 클로저 구문을 읽는 것입니다. 일단 당신이 모든 것이 더 합리적이라는 것을 이해하면.


Your questions are largely answered by the following:

Scala's For Comprehensions

Scala Yield

To summaraize: It's largely stylistic. Personally, I favor the functional methodology, but prefer the succinctness of comprehensions when dealing with nested loops.

ReferenceURL : https://stackoverflow.com/questions/4466362/for-expressions-versus-foreach-in-scala

반응형