스칼라는 없습니다 break
또는 continue
일부 루프 동작은 좀 더 생각한다, 그래서.
루프를 일찍 끝내려면 꼬리 재귀, 예외 또는 scala.util.control.Breaks
(예외를 사용하는)이 필요합니다.
이것에 대한 이론적 근거는 마치 goto
흐름을 흐릿하게하는 흐름 구조이며, 더 훌륭하고 덜 놀라운 방법으로 달성 될 수 있다는 것입니다.
그러나 같은 주장이 사용될 수있을 것 같습니다 return
.
스칼라는 왜 고의적으로 생략 break
하고 continue
있 return
었는가?
답변
휴식과 계속 :
에서 스칼라에 대한 이야기 , 마틴 오더 스키는 휴식을 포함하거나 슬라이드 (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))