스칼라는 왜 돌아 왔지만 깨지 않고 계속하지 않는가?


22

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

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

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

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

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


1
언어 작성자가 꼬리 재귀를 반복을 구성 하는 방법으로 생각한다고 상상할 수 있습니다 . 나는 그것을 상상할 수 break있고 continue추가적인 청소 기계가 필요합니다. OTOH return는 기능을 순서대로 종료하는 방법이며, 정리 기계는 이미 존재합니다.
9000

1
breakable { for { break; } }군더더기에 불과하고, 가능성이 훨씬 효율적에서.
Joop Eggen

함수를 사용하면 실제로 그 이유가 없습니다. 파이썬에서도 마찬가지입니다. for-loop를 break와 함께 사용할 때마다 대신 함수를 작성하고 함수에 루프를 넣고 return을 사용할 수 있습니다. 깨끗한 코드와 관련하여 좋은 생각이 아닌 상황을 생각할 수 없습니다. 퍼포먼스의 경우 클린이 더 나을 수 있지만 스칼라에서는 퍼포먼스가 우선 순위가 높지 않습니다.
valenterry

2
이 질문에 대한 답변이있는 것 같습니다 : stackoverflow.com/questions/3770989/…
Michael Shaw

3
@PaulDraper : 대한 대답 break하고는 continue귀하의 질문과 질문에있는 링크에 포함되어 있습니다. 에 대한 질문 return은 내가 연결 한 질문에 관한 것입니다. 두 개의 답변을 모두 모아서 질문에 대한 답변을 얻지 못하면 질문을 명확히하기 위해 편집 할 수 있습니다.
Michael Shaw

답변:


16

휴식과 계속 :

에서 스칼라에 대한 이야기 , 마틴 오더 스키는 휴식을 포함하거나 슬라이드 (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명령문이 사용되지 않더라도 메소드는 값을 종료하고 리턴 하므로 클로저에는 문제가 없습니다. 그렇지 않으면 클로저가 작동하지 않기 때문입니다.

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


2
반환에 관해서는, 약간의 경미한 위험이있는 것 같습니다 : tpolecat.github.io/2014/05/09/return.html
bbarker

0

이전 답변은 비교적 제약이없는 상황에서 스칼라에 대해 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))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.