'2016/01'에 해당되는 글 3건

  1. 2016.01.19 [Scala] Expression에 대해
반응형

 "expression"이란 실행되고 나서 어떤 값을 넘겨주는 코드이다. 하나 또는 그 이상의 코드라인이 expression이면 {}로 모아진다. 이를 "expression block"이라고 한다. immutable data는 새로운 데이터는 기존 변수에 저장하는 것이 아니라 새로운 값에 할당하는 개념이다. expression은 어떤 데이터에 대해서 새로운 데이터를 반환하며 계층적으로 하나의 expression을 다른 expression에 연계해서 값을 반환하게 할 수 있다.

 value와 variable을 정의하는 것도 expression으로 표현 가능하다.


val <identifier>[: <type>] = <expression>

var <identifier>[: <type>] = <expression>


 "statements" 는 값을 리턴하지 않는 expression이다. statements는 Unit를 리턴한다고 보면 된다. statement block은 값을 리턴하지 않기 때문에 데이터를 변경하거나 application의 범위 밖에 변화를 주기 위해서 사용된다. (예를 들어 console에 출력, database 업데이트, 서버 접속 등)


If-Else Expression Block

Scala에서는 if block과 else block만을 지원한다. (else if가 없다.) 단 if..else { if..else } 형태로 구현은 가능하다. if expression은 다음과 같다.


if (<Boolean expression>) <expression>


Boolean expression은 true 또는 false를 반환하는 expression이다.


scala> val condition="Hello"

condition: String = Hello

scala> val result=if(condition=="Hello") "World"

result: Any = World


반환값이 없으면 (), Unit를 반환한다.

다음은 if-else expression이다.


if (<Boolean expression>) <expression>

else <expression>


Match Expressions

C나 Java의 switch 문과 유사하다. 다음은 Match expression 이다


<expression> match {

case <pattern match> => <expression>

[case...]

}


=> 다음에 여러 expression이 올수 있다. <pattern match>에서는 | 을 이용하여 or condition을 이용할 수 있다.


scala> val httpstatus=201

httpstatus: Int = 201


scala> val message = httpstatus match {

     | case 200 | 201 =>

     | println("OK")

     | "OK"

     | case 400 =>

     | println("NOT FOUND")

     | "ERROR"

     | case 500 =>

     | println("INTERNAL ERROR")

     | "ERROR"

     | }

OK

message: String = OK


만약 일치하지 않은 pattern을 처리하려면 other라는 value를 쓰거나 _ 와일드카드를 사용하면 된다. 다음은 other 나 _를 이용한 사례이다.


scala> val httpstatus=202

httpstatus: Int = 202


scala> val message=httpstatus match {

     | case 200 => "OK"

     | case other =>

     | println(s"Unknown code $other")

     | "NOTOK"

     | }

Unknown code 202

message: String = NOTOK

scala> val httpstatus=202

httpstatus: Int = 202


scala> val message=httpstatus match {

     | case 200 => "OK"

     | case _ =>

     | println(s"Unknown code $httpstatus")

     | "NOTOK"

     | }

Unknown code 202

message: String = NOTOK


scala에서는 match expression에 if 조건 로직을 결합시킬 수 있다. 이를 "pattern guard"라고 한다. Pattern guard는 다음과 같이 사용한다. (if 문 다음에 ()가 없음을 참조하기 바란다)


case <pattern> if <Boolean expression> => < one or more expression>


다음은 pattern guard를 이용한 예제이다. (Int Code 200이 출력된다)


val httpstatus:Int = 200

httpstatus match {

case res if res.getClass.getSimpleName=="int" => println(s"Int Code $res")

case res if res.getClass.getSimpleName=="String" => println(s"String Code $res")

}


httpstatus를 val httpstatus:String="200"으로 상시 match문을 실행하게 되면 String Code 200이 출력된다. 


pattern matching을 하는 방법중 type을 비교하는 방법이 있다. 다음과 같이 type에 대해서 match문을 이용할 수 있다.


case <identifier>: <type> => < one or more expression>


다음은 그 예제이다.


val httpstatus:Int = 200

val httpany:Any = httpstatus

httpstatus match {

case res: String => println(s"String Code $res")

case res: Int => println(s"Int Code $res")

}


Loops

1) for-loop

다음은 for-loop에 대한 syntax이다.


for(<identifier> <- <iterator>) [yield] [expression]


yield는 선택사항인데, "yield"가 정의되어 있으면 yield에 해당하는 expression의 return 값에 대한 collection이 넘겨진다. 다음은 for문에 대한 예제이다.


val numString=List("one","two","three","four")

for(x<- 0 to 3 ) println(numString(x))

val yieldTst=for(x<- 0 to 3) yield numString(x)

yieldTst(0)

for(x<-numString) println(x+"-")

for(x<-yieldTst) println(x+"-")


이 예제에서 yieldTst는 Vector Type이다. for-loop은 map에 해당된다고 볼수 있다. map은 개별 멤버의 입력에 대해서 expression을 적용하는 것이다.

(iterator guard)

 pattern guard와 같이 iterator guard(또는 filter)를 for-loop문에 적용할수 있다. 다음은 iterator guard에 대한 syntax이다. if의 Boolean expression이 true일 경우에만 expression이 적용된다.


for(<identifier> <- <iterator> if <Boolean expression> ) [yield] [expression]


다음은 iterator guard 예제이다.


val evenNumber=for(x<-1 to 20 if x%2==0) yield x


(Nested Iterators)

 for문에 여러 iterator를 붙여서 nest loop 효과를 낼수 있다. 다음은 그 예제이다.


 scala>for(x<-1 to 2;y<- 1 to 3) yield (x,y)

res39: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,1), (1,2), (1,3), (2,1), (2,2), (2,3))


(Value Bindinig in For-Loops)

for-loop의 현재 iteration에서 임시 변수를 활용하는 것은 기본적인 활용 방법이다. Scala에서는 다음과 같이 for-loop를 정의하는 곳에 임시 변수를 활용할수 있도록 해준다.


for(<identifier> <- <iterator>;<identifier>=<expression>) [yield] [expression]


다음은 그 예이다.


 scala> val testVB=for(i<-0 to 10;multi=i*i if i%3==0) yield multi

testVB: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 9, 36, 81)

scala> val testVB=for(i<-0 to 10 if i%3==0) yield {

     | val temp=i*i

     | temp}

testVB: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 9, 36, 81)


While/Do-While Loops

다음은 while loop의 Syntax이다


while (<Boolean expression>) statement


do-while loops는 다음과 같다.


do statement while (<Boolean expression>)


다음은 그 예이다.


scala> var x=0;while(x<10) x=x+1

x: Int = 10

scala> do {

     | println(x)

     | x=x-1

     | } while (x>0)

10

9

8

7

6

5

4

3

2

1


Reference

Learning Scala, Oreilly

반응형
Posted by alias
,