프로그래밍/Scala

코딩 바보의 Scala 입문하기 두번째

seungdols 2015. 11. 20. 11:27
Scala

예제 한빛 미디어 - 세븐 랭귀지

Loop

기본적인 while 루프는 아래와 같다.

def whileLoop {
    var i = 1
    while(i <= 3) {
        println(i)
        i += 1
    }
}
whileLoop

스칼라의 함수는 기본적으로 public이 설정되어 있다.
for문의 경우에는 다른 언어와 조금 형식이 다르다.

def forLoop {
    println( "for loop using Java-style iteration" )
    for(i <- 0 until args.length) {
        println(args(i))
    }
}

forLoop

'초기값 until 마지막 값'의 형태를 갖는 범위가 오게 된다.

루비의 each와 비슷한 foreach도 존재한다.

def rubyStyleForLoop {
    println( "for loop using Ruby-style iteration" )
    args.foreach { arg => 
        println(arg)
    }
}

rubyStyleForLoop
scala> val range = 0 until 10
range: scala.collection.immutable.Range = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> range.start
res26: Int = 0

scala> range.end
res27: Int = 10

scala> (0 to 5) by 1
res28: scala.collection.immutable.Range = Range(0, 1, 2, 3, 4, 5)

scala> val range = (10 until 0)(-1)
java.lang.IndexOutOfBoundsException: -1
  at scala.collection.immutable.Range.apply$mcII$sp(Range.scala:151)
  at scala.collection.immutable.Range.apply(Range.scala:149)
  ... 33 elided

scala> val range = (10 until 0)by (-1)
range: scala.collection.immutable.Range = Range(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

scala> val range = (10 until 0)
range: scala.collection.immutable.Range = Range()

scala> val range = (0 to 10)
range: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)


scala> val range = 'a' to 'z'
range: scala.collection.immutable.NumericRange.Inclusive[Char] = NumericRange(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)

scala>

위 코드에서 보면 to의 경우 마지막 값을 포함하나, until은 마지막 값을 포함하지 않는다. 그리고 역으로 돌릴 수 있는데 그 때에는 -1로 방향을 지정해주어야 한다. 스칼라 컴파일러가 방향까지 유추하진 못한다.


튜플

스칼라는 튜플을 제공한다. 튜플은 길이가 고정된 객체 집합이다. 물론, 파이썬에서도 튜플이 존재한다. 튜플은 서로 자료형이 달라도 상관이 없다.

scala> val human = ("seungdols","seungdols comp")
human: (String, String) = (seungdols,seungdols comp)

scala> human._1
res29: String = seungdols

scala> human._2
res30: String = seungdols comp

아래와 같이 튜플을 이용해서 여러 변수에 한 번에 값을 넣어줄 수 있다.
튜플은 저장된 값을 이용해 정적 타이핑 검사를 수행할 수 있다.

scala> val (x,y) = (1,2)
x: Int = 1
y: Int = 2

Scala의 클래스
scala> class Human(firstName:String, lastName:String)
defined class Human

scala> val seungdols = new Human("seungdols","choi")
seungdols: Human = Human@47daf1

우선 위와 같이 선언할 수도 있지만, 더 알아보도록 하자.
아래 클래스를 살펴보자. 아래 클래스에서 중요한 특징을 찾을 수 있는데, 스칼라의 클래스 정의 부분에서 어떤 ‘함수’ 부분에 포함 되지 않은 부분이 Constructor(생성자)이다.

class Person(firstName: String) {
  println("Outer constructor")
  def this(firstName: String, lastName: String) {
    this(firstName)
    println("Inner constructor")
  }
  def talk() = println("Hi")
}
val bob = new Person("Bob")
val bobTate = new Person("Bob", "Tate")

class Person(firstName: String)//생성자 { println("Outer constructor") //this 이 부분이 보조 생성자이다. def this(firstName: String, lastName: String) { this(firstName)//메인 생성자 호출 println("Inner constructor") } }


짝 객체와 클래스 메서드

자바와 루비는 클래스 메서드와 인스턴스 메서드를 하나의 클래스 안에 만들 수 있었다.
자바에서 클래스 메서드는 static 키워드를 표시했고, 루비는 def self.class_method를 이용했다. 스칼라는 이런 방법을 이용하지 않는다. 인스턴스 메서드는 class 정의 내부에서 선언한다. 그리고 그것이 하나의 객체 인스턴스만 갖는 다면, class 키워드 대신 object 키워드를 이용한다.

object TrueRing {
 def rule = println("To rule them all")
}
TrueRing.rule

위 코드는 싱글턴객체를 생성한다.
클래스 메서드는 싱글턴 객체 선언 내에서, 인스턴스 메서드는 클래스 선언 내에서 선언할 수 있다.

class와 object를 같이 사용하는 방법을 companion Object(짝 객체)라고 부른다.


상속

스칼라에서 상속은 쉽다.

class Person(val name: String) {
  def talk(message: String) = println(name + " says " + message)
  def id(): String = name
}

class Employee(override val name: String, 
                        val number: Int) extends Person(name) {
  override def talk(message: String) {
    println(name + " with number " + number + " says " + message)
  }
  override def id():String = number.toString
} 

val employee = new Employee("Yoda", 4)
employee.talk("Extend or extend not. There is no try.")

생성자 및 확장하는 메서드는 앞에 ‘override’ 키워드를 반드시 작성해야 한다.


Trait

트레이트는 스칼라의 꽃이라 표현하고 싶다. (누가? 내가..)
C++는 다중상속, Java는 interface, Ruby는 mixin을 이용하므로, 스칼라도 뭔가를 이용해야 하지 않겠나. 그래서 트레이트를 사용하는데 이 개념은 Java의 interface의 개념으로 설명하면 구현된 interface라고 생각하면 될 것 같다. (물론 Java8에서 default 키워드로 method를 구현할 수 있게되었다.)

예시를 보고 배우자. 프로그래머는 예제로 배우면서 큰다.

class Person(val name:String)

trait Nice {
  def greet() = println("Howdily doodily.")
}

class Character(override val name:String) extends Person(name) with Nice

val flanders = new Character("Ned")
flanders.greet

코드를 보면 Person 클래스를 확장하면서 Nice 트레이트를 혼합하고 있는 것을 볼 수 있다. 이렇게 하면 Character 인스턴스는 greet를 호출 할 수 있다.

Java8에서 interface에 default 키워드 붙인 느낌이랑 비슷하다.

세븐 랭귀지의 Scala 부분의 내용입니다.


  •  무단 수정 및 배포는 금지합니다. 
  •  모든 내용은 본 블로그 운영자가 정리한 내용입니다. 
  •  참조한 정보에 대해서는 출처를 남기고 있습니다.
  •  다양한 곳에서 참조한 경우 출처 누락이 있을 수 있습니다.
  •  (말해주시면  수정하도록 하겠습니다.)
  •  틀린 내용 / 오류가 포함된 내용은 댓글로 남겨주세요.
  •  choiseungho0822@gmail.com 보내주셔도 됩니다.
  •  Seungdols Wiki 운영중입니다.



반응형

'프로그래밍 > Scala' 카테고리의 다른 글

코딩 바보의 Scala 입문하기 #3 Collection  (0) 2015.11.23
1급 객체 (First class Object)  (0) 2015.11.20
코딩 바보의 Scala 입문하기  (0) 2015.11.20