ABOUT ME

구르미의 개발 블로그입니다. 개발, Devops 관련 포스팅을 주로 다루고 있습니다.

Today
Yesterday
Total
  • [스칼라 문법편] CH01 스칼라 준비하기
    24년 11월 이전/레거시-누구나 쉽게 스칼라+플레이 2019. 1. 28. 22:12
    반응형

    * 이 포스팅은 책 "누구나 쉽게 스칼라+플레이 - 고락윤 한빛 미디어"를 읽고 정리한 것입니다.

    CH01 스칼라 준비하기

    01. 스칼라에 대해서...


    스칼라의 특징은 다음과 같습니다.

    1. 코드의 직관성과 신축성이 뛰어나다.

    스칼라는 기존 자바(여기서 기존 자바는 자바8 이전을 뜻합니다.)와 비교하여, 짧으면서 직관적인 코드 작성을 할 수 있습니다. 예를 들어서, 다음과 같이 사람을 나타내는 Person 클래스가 있다고 가정해봅시다.

    class Person{
        String name;
        int age;
        
        public Person(String name, int age){
            this.name = name;
            this.age = age;
        }
    
        public String getName(){
            return name;
        }
    
        public int getAge(){
            return age;
        }
        public void setName(String name){
            this.name = name;
        }
        public int getAge(int age){
            this.age = age;
        }
        
        @Override
        public String toString(){
            return "Person[name: + name + " age: " + age "]";
        }
    }


    자바에서는 이렇게 POJO 형식의 클래스를 만들 경우, 게터, 세터, toString, hashCode 등 만들어야할 메소드가 너무나도 많습니다. 기존 모던 언어에 비교하면 정말이지 지루한 작업이 아닐 수 없습니다. 스칼라에서는 다음과 같이 간단하게 표현할 수 있습니다.

    case class Person(name: String, age: Int)


    간단하지요? 또 한가지 예를 들어봅시다. 기존의 숫자들을 저장하는 숫자 리스트 list가 있다고 가정해봅시다. 여기서 5의 배수의 숫자만 골라내고 싶습니다. 기존 자바에서는 어떻게 표현할 수 있을까요?

    List<Integer> otherList = new ArrayList<>();
    
    for (Integer i : list){
        if (i % 5 == 0){
     	otherList.add(i);
        }
    }


    이 코드는 스칼라에서 단 한줄로 다음과 같이 표현할 수 있습니다.

    val otherList = list.filter( i => i % 5 == 0 )


    여기서 사용한 예제는 극히 기본적인 것이지만, 코드가 복잡해질수록, 장황해질수록, 스칼라의 이러한 특성 덕분에 우리는 보다 짧고 보다 유연한 코드 작성이 가능하답니다.

    1. 풍부한 표현식과 연산자가 존재한다.

    또한 스칼라에서는 같은 메소드라도 풍부하게 표현할 수 있으며 연산자 또한 개발자 입맛대로 오버로당하여 사용할 수 있습니다. 예를 들어서 클래스 Animal의 메소드 eat이 있다고 합시다. 그러면, 스칼라는 기본적으로 자바와 같이 메소드 호출하는 형식으로 메소드를 사용할 수 있습니다.

    animal.eat(fruit)


    또한, 위 코드는 다음과 같이도 사용할 수 있습니다.

    animal eat fruit


    또한, 자바에서 할 수 없었던, 연산자 오버로딩을 스칼라에서는 사용할 수 있습니다. 대표적으로 스칼라의 컬렉션 List는 ++ 연산자를 지원합니다. 이 연산자는 리스트와 리스트를 합친 리스트를 나타냅니다. 바로 이렇게 말이죠.

    list3 = list1 ++ list2 //list1 = [1, 2, 3], list2=[5,6], list3=[1, 2, 3, 5, 6]

    1. 동시성에 강하다.

    스칼라는 동시성 문제를 해결하는 방향으로 언어가 만들어졌습니다. 스칼라는 어떤 방식으로 동시성을 해결하냐면, 불변성과 함수형 프로그래밍 패러다임을 차용하여 해결합니다. 또한, 기존 자바에서철 OOP 스타일로도 코딩이 가능하기 때문에 동시성에 안전하면서도, 객체지향 코드처럼 유연하게 코드를 작성할 수 있습니다. 이러한 스칼라의 특성을 제일 잘 표현한 라이브러리 중에는 AKKA 라이브러리가 존재합니다. 액터 모델을 기초로 동시성을 훌륭하게 제어하는 라이브러리이죠. 이것은 나중에 시간이 되면 살펴보도록 하겠습니다. 책과 여기 저장소에서는 아카 웹 소켓만을 다루고 있습니다.

    1. 스칼라의 모든 것은 객체이다.

    스칼라에서는 모든 것이 객체입니다. 기본 자료형, 클래스, 함수, 연산자, 등 모든 것이 객체입니다. 매개변수에 함수를 집어넣을 수도 있으며, 변수에 할당도 가능합니다. 대표적인 것이 위에 나온 filter 인데, filter 매소드는 내부적으로 Int 형을 받아 Boolean 형을 반환하는 함수를 매개 변수로 받습니다.

    def filter(f: Int => Boolean): List<Int> ... 
    
    list.filter( (i) => (i % 5 == 0) )


    여기서 (i) => (i%5 ==0) 은 함수이며, 람다 식입니다. 이런 배경 지식을 알고 있다면 filter 매소드의 매개변수가 함수라는 것을 알 수 있습니다.

    1. 컴파일러가 맥락을 읽을 수 있다.

    컴파일러가 맥락을 읽을 수가 있다. 무슨 말일까요? 자바의 경우 하나하나 명시적으로 자료형을 지정하고, 매개변수를 써야 합니다. 하지만 스칼라에서는 implicit 키워드를 사용하여 명시적인 표현을 감출 수 있습니다. 때로, 프로그래밍을 하다보면 추가적인 데이터를 보내는 로직을 추가하기 위해 그와 관련된, 메소드 및 반환 형태를 변경해야 하는 경우가 있습니다. 스칼라에서는 이 키워드를 통해서 컴파일러가 알아서 맥락을 읽어 필요한 곳에 필요한 것을 할당해줄 수 있습니다. 이것에 대한 자세한 얘기는 나중으로 미루도록 하죠.

    1. 자바와 연계성이 뛰어나다.

    스칼라의 훌륭한 점은 자바의 라이브러리를 사용하는데 부담이 전혀 없다는 것입니다.(코틀린보다는 어렵지만...) 이러한 이유로 스칼라는 자바 진영으로부터 오랫동안숙련된 JVM 내의 언어이기 때문에 기타 다른 언어보다도 훨씬 안정적입니다. 이것은 입문 단계인 우리에게는 해당 사항이 없기 때문에, 넘어가겠습니다.

    스칼라의 대표적인 특징들을 간략하게 알아보았습니다. 어떤가요? 기존 자바 유저라면, 스칼라를 사용하는데, 아무런 부담(맞아??)이 없습니다. 기존 JVM 라이브러리를 그대로 사용하기 때문에 안정적이고, 성능도 빠르면서도 보다 뛰어나고, 간단한 코드 작성할 수 있습니다. 또한 현재, 빅데이터 분야에서 주로 쓰이는 언어 2가지 꼽으라면 파이썬과 스칼라가 있습니다. 주로 쓰이는 툴인 스파크가 스칼라로 만들어져있기 때문이죠. 우리가 스칼라를 배우는데, 더 이상의 이유는 필요 없습니다. 이제 본격적으로 배워보도록 하죠!

    02. 스칼라 개발환경 구축하기


    스칼라를 공부하기 전에 우리는 그에 맞는 개발환경을 구축해주어야 합니다. 이 저장소의 기준은 Mac OS로 하겠습니다. 리눅스, 윈도우 역시 구글링하면 금방 찾아보실 수 있을 겁니다. 시작하죠

    1. HomeBrew 설치하기

    먼저 맥의 패키지 매니저 HomeBrew를 설치해주어야 합니다. 먼저 홈 브루 페이지 이곳 에서 다음을 복사해주세요.

    $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


    그 후 터미널에 이것을 입력하시면, 홈 브루가 설치가 될 겁니다.

    1. JDK 설치하기

    홈 브루 설치가 완료되었으면 JDK를 설치하면 됩니다. 스칼라를 사용하기 위해서는 기본적으로 JDK 1.8 즉 자바 8 이상의 자바가 필요합니다. 일단은 현재 버전의 자바와 자바8을 설치하도록 하겠습니다 홈 브루를 설치했다면 자바 설치는 간단합니다. 다음을 터미널에 입력하시면 됩니다.

    $ brew install java
    $ brew tap caskroom/versions
    $ brew cask install java8


    이렇게 하면, 2019년 1월 현재는 JDK11이 default로 그리고 자바8이 깔리게 됩니다. 자바가 제대로 깔렸는지 알고 싶다면 터미널에 다음의 명령어를 사용하시면 됩니다.

    $ java -version


    터미널에 openjdk 11 이라는 문구가 출력된다면, 제대로 설치가 된 것입니다.

    1. 스칼라 설치하기

    이제 스칼라를 설치해봅시다. 쉽습니다. 다음을 입력하면 됩니다.

    $ brew install scala


    그러면 스칼라가 설치될 겁니다. 역시 설치가 제대로 됐는지 알고 싶다면, 다음을 터미널에 입력하시면 됩니다.

    $ scala -version


    2019년 1월 기준 스칼라 최신 버전은 2.12.8입니다. 터미널에 버전이 출력된다면 올바르게 설치된 것입니다.

    1. SBT 설치하기

    바로 IDE인 인텔리J를 설치해도 좋지만, 스칼라 전용 빌드 툴인 SBT를 설치하도록 하겠습니다. SBT란 간단하게 스칼라, 자바 의존성 라이브러리들을 보다 쉽게 프로젝트에 추가할 수 있는 도구라고 생각하시면 좋겠습니다. 바로 들어가죠. 터미널에 다음을 입력해주세요.

    $ brew install sbt


    끝입니다. 그러면 알아서 설치가 될 것입니다. SBT가 제대로 깔렸는지 알고 싶다면 터미널에 다음을 입력해주세요.

    $ sbt about


    그러면 버전 정보가 출력될 것입니다. 그러면, 현재 기준 sbt 1.2.8이 출력될 것입니다. 이 때 부가 정보도 출력되는데 무시하고 버전 정보만 확인하면 됩니다. 이제 마지막으로 IDE를 설치하도록 하죠.

    1. 인텔리J C/E 설치하기

    책에서는 Scala IDE로 진행하지만, 스칼라 IDE는 이클립스 기반으로 만들어졌기 때문에, 느린 편이 없지 않아 있습니다. 따라서, 개인적으로, 좋아하는 인텔리J를 설치하도록 하겠습니다. 이것은 자료가 너무나도 많기 때문에, 구글링 쳐보세요 ㅎㅎ 중요한 것은 스칼라 플러그인을 설치해야 한다는 것입니다.

    03. Hello Scala 분석하기


    1. Hello Scala 작성하기

    IDE를 이용해서 만들어도 좋고 그냥 텍스트 에디터를 이용해서 만들어도 좋습니다. 이것은 쉽기 때문에 따로 설명하지는 않겠습니다. 인텔리J에서는 자바 대신 언어를 스칼라로 선택해야 합니다. 아무튼 스칼라 파일 Main.scala를 작성하도록 하죠.

    object Main{
        def main(args: Array[String]):Unit = {
            println("Hello Scala!")
        }
    }
    1. Hello Scala 분석하기

    특별히 이 부분에서는 자바랑 다른점만 간략하게 파악하도록 하죠. 아래 똑같은 동작을 하는 자바 코드를 보고 스스로 분석한 뒤에, 제가 쓴 차이점이랑 비교하는 것도 좋을 것 같습니다. 다음은 위의 스칼라 코드와 똑같이 동작하는 자바 코드입니다.

    public class Main{
        public static void main(String[] args){
            System.out.println("Hello Java!");
        }
    }


    제가 파악한 차이점은 다음의 3가지입니다.

    1. object 키워드

    먼저 스칼라는 class 키워드도 존재하지만, object 키워드도 존재합니다. object 키워드는 해당 클래스를 싱글톤 객체로 만듭니다. 따라서, 객체의 상태가 공용으로 관리합니다. scala에서는 static 키워드가 없는데, 바로 static에 해당하는 모든 필드/메소드들이 object 클래스에 들어갑니다. 나중에 설명하겠지만, class와 object는 같은 이름으로 선언할 수 있습니다. 이를 동반객체라고 하는데 나중에 설명하도록 하겠습니다. 지금은 static 키워드를 모아두는 곳이라고 생각하면 편하실 겁니다.

    1. 세미콜론이 없다

    스칼라에서는 세미콜론을 강제하지 않습니다. 보통 직관적인 코드 작성을 위해서 한 줄에 여러 명령어를 사용하지는 않습니다. 따라서, 세미콜론의 존재가 별 쓸모 없이 작성되어야만 했습니다. 스칼라에서는 한줄에 한 명령어라면, 스크립트 언어처럼 세미콜론을 생략할 수 있습니다.

    1. 함수 원형이 다르다

    함수 원형 뿐 아니라, 변수 선어도 다릅니다. 보통, 자바에서는 자료형, 변수 명을 순서대로 사용합니다. 이처럼 말이죠.

    String[] args //매개변수
    
    static void main(String[] args) { ... } //함수 원형


    스칼라에서는 변수 명, 다음 자료형이 옵니다.


    args: Array[String] //매개변수
    def main(args: Array[String]): Unit


    여기서 Unit 타입은 void 형과 같습니다. 마지막으로 위 코드에서는 별 차이가 느껴지지 않는다고 생각하실 수 있습니다. 하지만, 다음 코드를 보면 의아할 수 있을 것 같습니다. 위 main 코드는 다음과 같이 변경할 수 있습니다.


    object Main{
        def main(args: Array[String]) = println("Hello Scala")
    }


    이에 대해서는 추후에, 설명을 하도록 하겠습니다. ㅎㅎ 어떠신가요? 스칼라 배워보고 싶나요? 배워보고 싶다면 다음 장 변수 다루기에서 만나요!

    728x90
Designed by Tistory.