일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- Akka
- Adapter 패턴
- 파이썬
- Hyperledger fabric gossip protocol
- Golang
- 그라파나
- 파이썬 머신러닝
- akka 강좌
- Play2 로 웹 개발
- play2 강좌
- 스칼라 동시성
- 엔터프라이즈 블록체인
- 이더리움
- Play2
- play 강좌
- 하이브리드앱
- hyperledger fabric
- 하이퍼레저 패브릭
- 파이썬 강좌
- 파이썬 동시성
- 스칼라 강좌
- 주키퍼
- 블록체인
- 스칼라
- Actor
- CORDA
- 파이썬 데이터분석
- 플레이프레임워크
- 안드로이드 웹뷰
- 스위프트
- Today
- Total
HAMA 블로그
스칼라 강좌 (11) - while 루프 와 재귀 본문
while
스칼라에서 While,For 문은 없다로 생각하는게 좋습니다.개인적으론 Java 8 이상에서도 while 문은 없다라고 생각하는게 좋지 않나 합니다.아래와 같이 다른 방법
Stream API
LINQ
STL algorithm
컬렉션의 고차함수(map , flatmap, filter, zip, fold, foreach, reduce, collect, partition, scan, groupBy 등)
을 먼저 생각하는게 좋습니다.
* 스칼라의 while 은 다른 언어와 마찬가지로 동작합니다.
* if 나 for 가 표현"식" 인 반면에 while 은 "식" 이 아닙니다. 그냥 루프입니다. 즉 값을 내어 놓지 않습니다.
예를들어 if 표현식의 경우 값을 내놓기 때문에 아래와 같이 코딩이 가능합니다.
val filename = if (!args.isEmpty) args(0) else "default.txt"
예제
// 20 번 돌겠군요.
var a = 0;
while( a < 20 ){
a = a + 1;
}
보통 while 문들 처럼 조건을 검사하고 조건이 참일때까지는 계속 반복 수행을 합니다.
do while 루프도 있습니다.
var a = 0;
do {
a = a + 1;
} while( a < 20 )
조건에 상관 없이 적어도 한번은 실행 할 수 있겠네요. ( 위의 코드에서는 20번 )
Unit 타입
루프의 결과는 그 타입이 Unit 입니다. 이 타입은 유니트 값 밖에 없으며 빈 괄호 () 로 표시합니다.
() 란 값이 존재한다는 점에서 자바의 void 와 다릅니다.
def greet() { println ("hi")} 를 실행하면 () 이며 var 변수에 대한 재 할당도 () 가 결과가 됩니다.
var line = 0;
while ((line = readLine()) != "") // 제대로 작동하지 않음 !!
println ("Read: " + line)
( line = readLine() ) 를 평가하면 () 가 나오는데 != "" 이런식으로 비교하면 언제나 참입니다.
자바의 경우 할당받은 결과 값이겠지만, 스칼라에서 할당의 결과는 유니트 값인 () 이기 때문입니다.
따라서
import java.io.File import scala.io.Source
Source.fromFile(new File("myfile.txt")).getLines.foreach {
line => println(line)
}
이런 방법을 고려해야 합니다. 사고 방식이 바뀌어야 한다는 말입니다.
이런식의 해결은 지양하고 있습니다.
while( {line = reader.readLine(); line!= null} ) { .... }
While 에서 탈출하기
2.8 버전부터 Breaks 가 생겼네요.
import scala.util.control.Breaks._
var largest = 0 // pass a function to the breakable method breakable
{
for (i<-999 to 1 by -1; j <- i to 1 by -1) {
val product = i * j
if (largest > product) {
break // BREAK!!
}
else if (product.toString.equals(product.toString.reverse)) {
largest = largest max product
}
}
}
순수 함수형 언어에서 while
순수 함수형 언어에서는 while 의 결과가 특정 값을 내보내는게 아니기 때문에 종종 제외합니다. 그런 언어에서 "루프" 는 없습니다.하지만 스칼라에서는 존재하는데 때로는 명령형의 해법이 가독성이 더 뛰어나다고 믿기 때문입니다.
재귀를 통한 while의 대체
재귀와 while 은 공통점이 몇가지 있습니다.둘다 body 를 반복한다는 점이구요. 콘디션을 점검해서 순회의 종료를 알린다는 점입니다.
위의 최대공약수 예제를 재귀로 바꾸어 보겠습니다.
// 최대 공약수 구하기
def gcd (x : Long, y :Long) : Long =
if (y == 0) x else gcd (y, x%y)
while 문의 컨디션 점검하는위치가 body 내부로 들어왔다는 점하고
함수이름을 호출함으로써 순회가 돌아진다는 점이 조금 달라졌을 뿐입니다.
* var 함수사용이 없어졌습니다.
일반적으로 while 루프틑 var 변수와 마찬가지로 적게 사용하기 위해 노력할것을 권장합니다.
while vs 재귀 vs 콜렉션 (고차함수)
이 3가지에 관한 글을 링크했습니다.
http://blog.richdougherty.com/2009/04/tail-calls-tailrec-and-trampolines.html
http://www.scala-lang.org/old/node/8113.html
http://alvinalexander.com/scala/scala-recursion-examples-recursive-programming
http://stackoverflow.com/questions/12496959/summing-values-in-a-list
http://stackoverflow.com/questions/18674743/is-there-any-advantage-to-avoiding-while-loops-in-scala
http://stackoverflow.com/questions/18645936/is-recursion-in-scala-very-necessary
'Scala' 카테고리의 다른 글
스칼라 강좌 (13) - 클래스와 객체 (0) | 2016.07.16 |
---|---|
스칼라 강좌 (12) - 객체의 동일성 (0) | 2016.07.08 |
스칼라 강좌 (10) - 공변성,불변성,역공변성 (0) | 2016.06.27 |
스칼라 강좌 (9) - Stack / Queue (0) | 2016.06.26 |
스칼라 강좌 (8) - ArrayBuffer 와 Vector 그리고 공변성 (0) | 2016.06.26 |