스칼라는 왜 돌아 왔지만 깨지 않고 계속하지 않는가? 일찍 끝내려면 꼬리

스칼라는 없습니다 break또는 continue일부 루프 동작은 좀 더 생각한다, 그래서.

루프를 일찍 끝내려면 꼬리 재귀, 예외 또는 scala.util.control.Breaks(예외를 사용하는)이 필요합니다.

이것에 대한 이론적 근거는 마치 goto흐름을 흐릿하게하는 흐름 구조이며, 더 훌륭하고 덜 놀라운 방법으로 달성 될 수 있다는 것입니다.

그러나 같은 주장이 사용될 수있을 것 같습니다 return.

스칼라는 왜 고의적으로 생략 break하고 continuereturn었는가?



답변

휴식과 계속 :

에서 스칼라에 대한 이야기 , 마틴 오더 스키는 휴식을 포함하거나 슬라이드 (22) 계속하지 않는 3 가지 이유를 주었다 :

  • 그것들은 약간 필수적입니다. 많은 작은 기능을 더 잘 사용하십시오.
  • 클로저와 상호 작용하는 방법을 설명합니다.
  • 그들은 필요하지 않습니다!

그리고 그는 “우리는 도서관에서 순전히 지원할 수 있습니다”라고 말합니다. 슬라이드 23에서 그는 구현하는 코드를 제공합니다 break. 내가 아주 충분히 특정 할 수 스칼라를 알 수 없지만, 그 슬라이드의 짧은 조각을 구현하는 데 필요한 모든처럼 보이는 break, 그리고는 continue유사 짧은 코드로 구현 될 수있다.

라이브러리에서 이와 같은 것을 구현할 수 있으면 핵심 언어가 단순화됩니다.

Martin Odersky, Lex Spoon 및 Bill Venners의 ‘Scala 프로그래밍, 2 판’에는 다음과 같은 설명이 제공됩니다.

break또는에 대한 언급이없는 것을 알 수 있습니다 continue. 스칼라는 함수 리터럴과 잘 맞지 않기 때문에 이러한 명령을 생략 continue합니다. while루프 내부의 의미 는 분명 하지만 함수 리터럴 내부의 의미는 무엇입니까? … break및 없이 프로그램하는 방법에는 여러 가지가 있으며 continue함수 리터럴을 활용하면 이러한 대안이 원래 코드보다 짧을 수 있습니다.

반환:

return은 스타일을 나타내는 명령으로 간주 될 수 있습니다. return은 동사이며 무언가를 수행하는 명령이기 때문입니다. 그러나 순전히 기능적 / 선언적 방식으로도 볼 수 있습니다. 함수의 리턴 값이 무엇인지 정의합니다 (여러 리턴이있는 함수에서 각각 부분 정의 만 제공하더라도).

같은 책에서 그들은 다음에 대해 말합니다 return.

명시적인 return문 이 없으면 Scala 메서드는 메서드에서 계산 한 마지막 값을 반환합니다. 메소드의 권장 스타일은 실제로 명시 적, 특히 여러 return명령문을 사용하지 않는 것입니다. 대신, 각 메소드를 하나의 값을 생성하는 표현식으로 생각하면 리턴됩니다.

return명령문이 사용되지 않더라도 메소드는 값을 종료하고 리턴 하므로 클로저에는 문제가 없습니다. 그렇지 않으면 클로저가 작동하지 않기 때문입니다.

함수는 값을 반환해야하기 때문에 함수 리터럴로 잘 맞 물리는 데 문제가 없습니다.


답변

이전 답변은 비교적 제약이없는 상황에서 스칼라에 대해 break또는 continue언어 전체 방식으로 의미를 정의하는 문제에 대한 정의를 수행한다고 생각합니다 .

내가 쓴 작은 도서관을 하도록 정의 break하고 continue보다 제약 맥락에서 : 반복 시퀀스를 통해 스칼라를 통해를위한 함축. 그 맥락에 집중함으로써, 나는 시맨틱 스가 모호하지 않고 추론하기 쉽다고 믿는다.

라이브러리는 https://github.com/erikerlandson/breakable에서 제공됩니다.

다음은 코드에서 어떻게 보이는지에 대한 간단한 예입니다.

scala> import com.manyangled.breakable._
import com.manyangled.breakable._

scala> val bkb2 = for {
     |   (x, xLab) <- Stream.from(0).breakable   // create breakable sequence with a method
     |   (y, yLab) <- breakable(Stream.from(0))  // create with a function
     |   if (x % 2 == 1) continue(xLab)          // continue to next in outer "x" loop
     |   if (y % 2 == 0) continue(yLab)          // continue to next in inner "y" loop
     |   if (x > 10) break(xLab)                 // break the outer "x" loop
     |   if (y > x) break(yLab)                  // break the inner "y" loop
     | } yield (x, y)
bkb2: com.manyangled.breakable.Breakable[(Int, Int)] = com.manyangled.breakable.Breakable@34dc53d2

scala> bkb2.toVector
res0: Vector[(Int, Int)] = Vector((2,1), (4,1), (4,3), (6,1), (6,3), (6,5), (8,1), (8,3), (8,5), (8,7), (10,1), (10,3), (10,5), (10,7), (10,9))