기본 콘텐츠로 건너뛰기

라벨이 scala인 게시물 표시

chap 14. 패턴매칭과 케이스클래스

1. switch-case scala> ch match { | case '+' => 1 | case '-' => - 1 | case _ => 0 | } 스칼라에서 사용하는 switch-case 이다. _ 으로 default 문의 역할을 할 수 있다. break 문이 안보이는게 기본적인 특징이다. 스칼라에서는 match-case를 자바보다는 좀더 자주 사용하는듯하다. 2. 가드 가드를 사용할 수 도 있다. scala> ch match { | case i if i == 1 => "one" | case i if i == 2 => "two" | case _ => "some other number" | } scala> ch match { | case x : Int => x | case s : String => Integer.parseInt(s) | case _ : BigInt => Int.MaxValue | } 그리고 변수를 활용하기도하고, asInstanceOf와 같은 형식으로도 많이 사용한다. switch-case문을 조금더 동적으로, 제네릭하게 사용할 여지가 생긴다. 3. case class 패턴칭매에서 편하기 사용하기 위한 클래스이다.  - new를 사용하지 않고 인스턴스를 생성 가능  - toString, equals, hashCode, copy 메소드 생성 scala> case class Calculator (brand: String , model: String ) defined class Calculator 인스턴스생성 scala> val hp20b = Calculato...

chap13 콜렉션 (Collections)

1. 콜렉션 계층도 scala의 콜렉션 계층도는 이렇다. 크게, set,map,seq http://docs.scala-lang.org/tutorials/FAQ/collections.html 2. 수정가능한 콜렉션과 수정불가능한 콜렉션  앞의 Map 을 다룰때 한번 나왔었다, immutable, mutable한 Map  수정불가능한것은 값이 변하지 않으니 안전하게 참조할 수 있어 좋다.  스칼라에서는 별도 명시가 없을 경우 immutable 한 경우로 취급한다. 3. 시퀀스  Vector는 Arraybuffer의 수정불가능한 버전, 각노드가 32개까지 자식을 가질 수 있는 트리로 구현된다. 백만개의 원소가 있는 벡터는 4개의 노드 레이어가 필요(10의6승 ~ 32의4승) 그래서 4번만의 접근이 가능.  Range는 시퀀스의 모든값을 저장하지 않는다. 시작, 종료, 증가분만 저장, to, until 메소드로 생성된다. 4. 리스트 scala> val digits = List(4,2) digits: List [ Int ] = List ( 4 , 2 ) scala> digits.head res0: Int = 4 scala> digits.tail res1: List [ Int ] = List ( 2 ) scala> digits.tail.head res2: Int = 2 :: 연산자로 리스트 멤버를 추가 scala> 9 :: digits res4: List [ Int ] = List ( 9 , 4 , 2 ) List에서 원소들을 방문할때 이터레이터를 사용하지만 스칼라에서는 재귀를 사용하는게 자연스럽다 scala> def sum (lst: List [ Int ]): Int = | if (lst== Nil ) 0 else lst.head + sum(lst.tail) sum: (lst: List [ Int ]) Int...

chap 12 고차함수 (high-order-function)

고차함수   - 함수를 인자로 받거나, 리턴해주는 함수 1. 값으로서 함수   - 함수를 변수에 저장할수 있다. scala> val fun = ceil _ fun: Double => Double = < function1 > ceil은 임의수보다 크거나 같은 수 가장 작은 수를 리턴해주는 함수이다. 기술적으로 _는 ceil 메소드를 함수로 바꾼다. 스칼라에서 메소드는 조작할 수 없고, 오직 함수만 가능. 2. 익명함수 scala> Array ( 3.14 , 1.42 , 2.0 ).map((x: Double )=> 3 *x) res5: Array [ Double ] = Array ( 9.42 , 4.26 , 6.0 ) 익명클래스도 그렇고, 이제는 익명이 조금 익숙해지기 시작한다. 함수의 실행순서가 중요해보인다. 3. 함수인자를 받는함수 scala> def mulBy (factor : Double ) = (x : Double ) => factor * x mulBy: (factor: Double ) Double => Double scala> val quintuple = mulBy( 5 ) quintuple: Double => Double = < function1 > scala> quintuple( 20 ) res7: Double = 100.0 quintuple 은 mulBy(5) 즉, (x:Double) => 5 * x 를 리턴한다. mulBy는 어떤 값을 곱하는 함수를 생성한다. 팩토리 같기도하고 클래스 같기도하고..  ㅎ 4. 인자추론 scala> def valueAtOneQuarter (f:( Double ) => Double ) = f( 0.25 ) valueAtOneQuarter: (f: Double => Double ) Double sca...

chap 10. trait

trait. 일단 java의 interface 같은 놈인듯 한데, 뭔가 다른게 있는것 같다. 1. 다중상속의 문제 아래의 Student, Employee개의 부모클래스가 있고, 이둘을 상속하는 TeachingAssistant 라는 클래스가 있다. class Student { def id : String = ... } class Employee { def id : String = ... } class TeachingAssistant extends Studet, Employee { .. } 그런데 문제는 두개의 부모클래스가 id라는 공통되는 변수를 가진다면 상속받는 클래스에서는 어떤 id를 택하게 될까라는 고민거리가 생긴다. 또 다이아몬드상속문제(Student와 Employee 역시 Person이라는 클래스를 상속한 서브클래스였다면)가 발생했을시 어떻게 할까, C++에서는 '가상 베이스 클래스' 라는 기능을 사용하고, 자바에서는 다중상속을 지원하지 않고, 인터페이스는 추상 메소드만 가질수 있고 필드는 가질 수 없게 한정하였다. scala에서는 이러한 다중상속문제 다루기위해 trait을 사용한다. 2. trait가 있는 오브젝트 trait는 자바의 인터페이스 기능을 수행한다. 인터페이스처럼 함수 구현부는 없이 사용할 수도 있지만, trait Logger { def log (msg: String ) } 인터페이스와는 달리 일반클래스처럼 함수를 구현해놓을 수도 있다. trait ConsoleLogger  extends Logged { def log (msg: String ){println(msg)} } 그리고 후자의 경우는 trait이 클래스의 믹스인 되었다 라는 표현을 사용한다. 그리고 믹스인이 된 클래스들은 trait이 변경되면 믹스인한 모든 클래스가 재 컴파일 되야하니 알고쓰자. 오브젝트를 생성할때 trait를 추가할 수 있다. trait ...

scala 8. 상속

1. extends 상속은 자바와 마찬가지로 extends 라는 키워드를 사용 class Person { var name = "" override def toString = getClass().getName + "[name=" + name + "]" } ... class Employee extends Person{ var salary = 0.0 override def toString = super .toString + "[salary=" + salary + "]" } 상속을 막고 싶으면 final을 사용 2. override 오버라이드(함수를 상속받아 재정의, cf 오버로드-함수의 파라미터 갯수를 달리하여 재정의)를 할경우 추상메소드인경우에는 그냥 진행하면 되지만, 그렇지 않은경우 메소드 앞에 override를 붙여준다. class Person { var name = "" override def toString = getClass().getName + "[name=" + name + "]" } ... class Employee extends Person{ var salary = 0.0 override def toString = super .toString + "[salary=" + salary + "]" } 실행 object test { def main (args: Array [ String ]): Unit ={ var ch = new Employee println(ch.toString) } } < result > [name=][salary= 0.0 ] 3. 슈퍼클래스 생성자 - java에서 부모클래스의 생...

scala 6. object

오브젝트 보통 클래스로부터 생성한 객체를 오브젝트라 칭한다. scala서 오브젝트는 위의 개념이 아니다. 1. 싱글톤  object로 생성되는건 싱글톤이다. 싱글톤 객체로 사용하고 싶을때 object를 사용한다 2. 컴패니언오브젝트( http://www.scala-lang.org/api/2.11.6/#scala.annotation.meta.companionObject )  컴패니언뜻은 동료, 동반자, 친구 뭐 이런뜻이다.  발번역하면 클래스와 친구인 오브젝트.. 뭐 이런건가 ㅋ  오브젝트는 위에서 말한것처럼 정적인 객체다, 정적인 필드와 메소드를 가지고 있다.  클래스에서 일부 정적인 기능이 필요한 경우 사용하라고 만들었다. class Account { val id = Account .newUniqueNumber() private var balance = 0.0 def deposit (amount : Double ): Unit ={ balance += amount } } object Account { private var lastNumber = 0 private def n zjaewUniqueNumber()={ lastNumber += 1 lastNumber } } Account컴패니언 오브젝트를 생성했다. Account의 인스턴스가 생성되면 고유한 ID값을 부여할 수 있다. scala> var ac1 = new Account ac1: Account = Account @35ff8fc9 scala> var ac2 = new Account ac2: Account = Account @29c2c826 scala> ac1 res10: Account = Account @35ff8fc9 scala> ac1.id res11: Int = 1 scala> ac2.id r...

scala 5. class

1. 클래스 scala> class Counter { | private var value = 0 | def increment () { value += 1 } | def current () = value | } defined class Counter 앞에서 했던 내용들하고 비교해보면 특별한건 없어보인다. 단 파라미터가 없는 메소드의 경우 가급적 '( )' 없이 사용하길 권장한다고 한다. 2. 게터와 세터 자동생성 scala> class Person { var age = 0 } defined class Person scala> val chang = new Person chang: Person = Person @157fe3d class 내부에 age라는 변수만 초기화 해놨다. 별다른 표시가 없으면 멤버 접근권한은 기본적으로 public으로 존재한다. scala> chang.age res9: Int = 0 scala> chang.age = 1 chang.age: Int = 1 scala> chang.age res10: Int = 1 이부분이 조금 매력적이다. 사용할때는 .age 하나인데, 이걸로 setter도 되고 getter의 기능도한다. scala에서는 만약 멤버변수 int타입 age가 생성되면 getter는 int age() = age setter는 void age_=(int) 의 형식으로 자동으로 내부적으로 생성한다. 그리고 멤버 변수가 var가 아닌 val으로 선언했다면 그 멤버의 setter는 생성되지 않는다. 또한 getter와 setter는 자동으로 생성은 됬지만, 입맛에 맞게 수정하여 사용할 수 도 있다. 3. 비공개필드 클래스에서 일부 필드를 비공개로 숨기는 기능이 있다. 대게 private한 변수들도 메소드내에서는 접근이 가능하다. 그런데 여기서는 ...

scala 4. map

http://www.scala-lang.org/api/current/#scala.collection.Map array 할때 느끼긴 했지만, map에서도 scala가 java보다 메소드가 훨씬 많다. 예를들어 별도로 array들의 sum을 구하기위해 for문을 돌릴 필요가 없다. 즉, 코드 사용량이 줄어든다. 에러날 건덕지가 줄어든다. 뭐 이런 유익한 장점들이 map에서도 보인다. 1. map 선언 scala> var scores = Map ( "Alice" -> 10 , "Bob" -> 3 , "Cindy" -> 8 ) scores: scala.collection.immutable.Map [ String , Int ] = Map ( Alice -> 10 , Bob -> 3 , Cindy -> 8 ) map 선언구문이다. '->' 이란 연산자는 쌍을 만드는 역할을 한다. (java에서 처럼 ',' 을 사용해도 가능) var 으로 선언했지만 기본적으로 immutable 한 성격을 가지고 있다. (변경불가) 물론 mutable하게 선언하면 mutalbe하게 사용할 수 있으니 걱정은 안해도됨. 2. 원소 접근 array처럼 (key) 으로 가능하고, java처럼 .get(key) 형태로도 접근이 가능하다. 그런데 둘의 용도는 조금 다를 수 있다. scala> scores( "Alice" ) res6: Int = 10 scala> scores.get( "basdf" ) res7: Option [ Int ] = None get 메소드를 사용할 경우 'Option' 이라는 object가 등장하는데, 이놈의 뜻은 값이 있을수도 있고, 없을 수도 있다. 없다고 해서 예외를 뱉진 않겠다. 뭐 이런거라고 한다. 꽤나 유용할듯. val ...

scala 3. 배열

scala에서 배열은 고정길이로 사용할건지, 가변으로 사용할건지로 구분을 둔다. 1. 고정길이 : Array scala > val nums = new Array[Int](10) nums : Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) int형 10칸짜리 array 초기화했다. 값을 설정하고 싶을때는, scala > val s = Array( "hello" , "world" ); s : Array[String] = Array(hello, world) 2. 가변길이 : ArrayBuffer 자바에서 ArrayList C++에서는 vector scala > val b = ArrayBuffer[Int]() b : scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer() 원소를 추가하거나 삭제할때는 대강 이렇다. scala > b+=1 res3 : b.type = ArrayBuffer(1) scala > b+=(2,3,4,5) res4 : b.type = ArrayBuffer(1, 2, 3, 4, 5) scala > b+=(1,2,3) res5 : b.type = ArrayBuffer(1, 2, 3, 4, 5, 1, 2, 3) scala > b.trimEnd(3) scala > b res7 : scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5) scala > b.insert(2,99) scala > b res9 : scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 99, 3, 4, 5) scala > b.remove(2) res10 : Int = 99 scala > b.remove(2,3) scala > b res1...

scala 2. 제어구조와 함수

이번에는 가장많이 쓰는 조건,반복,함수에 대한 내용이다. 1. scala는 if문 자체가 값을 가진다. scala> val s = if(x > 0) 1 else -1 s: Int = 1 scala> x res31: Int = 1 보통의 언어에서는 이렇게 표현할것이다.  사소하지만 편하긴하다. if(x > 0) s= 1 else s= -1 위에서는 1이라는 int타입을 예제로 했지만, 어떤타입이 와도 상관없다. 이걸보니 조금 더 편한것 같은 생각도 든다. scala> val s = if(x > 0) "a" else "b" s: String = a 2. Unit  = 값없음  Unit는 값없음을 나타낼때 사용하는 타입이다. java에서 void같은 느낌이라고 생각하면 된다고 한다. 3. 구문종료, 세미콜론(;)  보통 문장의 끝을 세미콜론으로 장식한다.  scala에서도 세미콜론을 사용해도 문제는 없다.  그런데 세미콜론을 굳이 안써도 상관없어 보인다.  단, 한줄에서 여러줄의 문장을 작성할 경우  문맥상 라인이 바껴야 할때는 세미콜론을 표시해죠야 한다. scala> var r = 3 r: Int = 3 scala> var n = 2 n: Int = 2 scala> {r = r * n n -=1} <console>:1: error: ';' expected but integer literal found. {r = r * n n -=1} ^ scala> {r = r * n; n -=1} 4. 블럭{}도 값을가진다.  {}도 if문처럼 값을 가진다. scala> val s = { x * x } s: Int = 1 scala> x res37: Int = 1 만약 {}이 2줄이상일경우라면, 가장 마지막에...

scala 1.기본

요새 okky에서 scala와 java가 조금 시끄러웠다. oracle이 java를 인수하면서 다소 폐쇄(?)적인 성향을 가지게 되었고, 신기술로 무장된 새로 생겨나는 언어들과 C와 같은 기존의 다른 언어들보다(모던C++) 발전속도가 느리다는게 요지인듯 하다. 그리고 그 대안중 하나가 scala였다. 요새 또 잘나가는 spark도 scala로 만들었다고 하니 겸사겸사 scala가 뭔지 좀 훑어보기로 했다. scala   http://www.scala-lang.org scala는 함수형언어+객체지향형 언어이다. 그리고 jvm에서 동작한다. 그렇다면 일단 java하고 비슷하다고 생각하면서, 함수형언어로써 뭐가 다른지 봐야할것 같다. 1. scala 변수 선언 var, val scala에서 변수를 선언하는 방법은 두가지다. var 그리고 val val : 변경불가, java의 final과 같은개념 var : 변경가능 val 으로 선언한 이후에 이것을 변경하려고 하면 error가 발생한다. scala> val x = 1 x: Int = 1 scala> var y = 1 y: Int = 1 scala> x = 2 <console>:14: error: reassignment to val x = 2 ^ scala> y = 2 y: Int = 2 var로 선언해서 int로 타입변환이 자동으로 이루어지는게 javascript와 유사하다. 2. RichInt,RichDouble,RichChar,StringOps scala가 가지고 있는 조금 특별한 클래스다, 용도는 int,double,char, string들에게 조금 더 많은 함수를 사용하기 위해 만들어진 클래스라고 한다. 즉 string 타입의 경우 stringOps의 함수를 사용할 수 있게끔 내부적으로 변환해준다. http://www.scala-lang.org/api/current/#scala.ru...