ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [스칼라] 기본 타입과 연산
    스칼라 2022. 1. 30. 02:16

    Programming in Scala 4th edition을 읽고 정리한 글입니다.

     

    스칼라의 기본 타입은 Byte, Short, Int, Long, Char, String, Float, Double, Boolean 이 있다. 자바의 타입과 상당부분 유사하므로 기본적인 내용은 생략하고 알아둬야할 것만 정리하기로 한다.

     

    1. raw 문자열

    긴 문자열을 표현하거나 escape문자열이 많이 들어가는 경우를 지원하기 위해서 스칼라에는 raw문자열이라는 문법이 있다.

    println("""hihi
          abcdef
         test
        """
    )
    
    //출력결과
    hihi
          abcdef
         test

    raw문자열은 위와 같이 입력된 형태 그대로 출력한다. 만약 공백을 제거하고 싶으면 아래와 같이 할 수 있다.

    println(
      """
        |abcd
        |sdflkj
        |""".stripMargin)
        
    //출력결과
    abcd
    sdflkj

    intellij에서는 """입력후 엔터키를 입력하면 stripMargin이 자동으로 적용된다.

     

    2. 심볼

    스칼라에는 단순 이름으로 사용되는 문자열을 위한 객체인 심볼이 있다. 예를들면 어떤 데이터베이스 열의 이름이 age 인경우에 'age와 같이 표현하는 것이다. 이렇게 단순 이름을 위한 문자열은 val 변수에 담아두는것보다 심볼을 사용하는것이 성능과 메모리 측면에서 약간의 이득이 있다. 스칼라 2.13부터는 Symbol("age")로 쓰도록 변경되었다.

    'age // val res2: Symbol = Symbol(age)

     

    3. 문자열 인터폴레이션

    문자열 인터폴레이션은 변수를 활용해서 문자열을 표현하고 싶을때 유용하다. 아래와같이 s"", raw"", f""의 세 가지 인터폴레이션을 제공한다.

    val name = "testUser"
    val age = 30
    println(s"Name: $name, Age: $age, Born in ${2022 - age}") 
    // 출력 Name: testUser, Age: 30, Born in 1992
    
    println(s"\\ \" \"")    // s는 이스케이프 문자 적용   \ " "
    println(raw"\\ \' \"")  // raw는 이스케이프 문자 출력 \\ \' \"
    
    val temperature = 10.2
    println(f"${math.Pi}%.5f, ${temperature}%20.2f") // f는 printf 형태가 적용되어 출력

    $와 ${} 를 이용해서 변수를 문자열 안에 표현할 수 있다. 따옴표 앞에 붙는 prefix에 따라 약간의 차이가 있다. s는 이스케이프 문자를 적용하고, raw는 이스케이프 문자를 그냥 출력시키는 차이가 있고, f는 printf 포맷이 적용된다.

     

    4. 연산자는 메서드다

    스칼라에서 연산자는 실제로는 메소드 호출을 편리하게 할 수 있도록 하는 문법이다. 예를 들어서 1 + 2 는 1.+(2)와 같다. Int 클래스 안에 +메서드를 호출하는 것이다. IDE에서 Int 객체가 가지고 있는 메서드를 찾다보면 아래와같이 연산자를 이름으로 한 메서드들을 볼 수 있다.

    1+2, 1*2와 같은 문법은 +, * 같은 연산자만 가능한 것이 아니고 일반적인 메서드도 중위 연산자 표기법으로 호출할 수 있다.

    //연산자
    class CalculateSymbol {
      var String = "Prefix"
      def concat(s: String): String = {
        s"$String $s"
      }
    }
    
    val calculateSymbol = new CalculateSymbol
    println(calculateSymbol concat "def")
    
    // 출력결과: Prefix def

    전위 연산자는 +, -, !, ~ 4가지만 정의할 수 있고 unary_+, unary_-, unary_!, unary_~를 정의해야한다. -1 같은 표현은 Int 객체 내에 unary_-를 호출한 것이다.

    후위 연산자는 인자가 없는 메서드를 .나 괄호 없이 호출하는 경우이다.

    //전위, 후위 연산자
    class PrefixPostfix {
      var s = "PREFIXPOSTFIX"
    
      def unary_+() = 1
    
      def toLowerCaseS(): String = {
        s.toLowerCase()
      }
    }
    
    val prefixPostfix = new PrefixPostfix
    println("abcd" toUpperCase)
    println(+prefixPostfix)
    print(prefixPostfix toLowerCaseS)
    // 출력 결과
    ABCD
    1
    prefixpostfix

     

    5. 객체 동일성

    스칼라에서 두 객체가 같은지 아닌지 비교하려면 ==와 !=을 사용하면 된다. 스칼라의 ==는 객체의 동일성을 검사하기 때문에 List 같은 곳에도 사용할 수 있다. 참조 비교는 eq메소드를 사용한다.

    // 객체 동일성
    val a = List(1, 2, 3)
    val b = List(1, 2, 3)
    println(a == b)   //true
    println(a.eq(b))  //false
    
    println(s"${1 == 1.0} ${1 == 1.0f}") // true true 타입이 달라도 비교 가능
    println(s"${1 == null} ${null == null}") // null도 비교해볼수 있다.

     

     

    6. 연산자 우선순위

    스칼라는 연산자 뒤에 등호가 붙지 않은 경우를 제외하고는 가장 첫 연산자를 보고 연산자 우선순위를 판단한다. (할당 연산자는 우선순위가 가장 낮다. +=, *= 같은 것들)

    연산자 우선순위가 같을때는 결합법칙이 적용되는데, 메서드 이름이 : 으로 끝나면 오른쪽부터 왼쪽으로, 그외에는 왼쪽부터 오른쪽으로 계산한다.

    // 연산자 우선순위
    class Order(arg: Int) {
      val n = arg
      def ::::(o: Order): Order = {
        println(o.n, n)
        new Order(o.n + n)
      }
      
      def ***(o: Order): Order = {
        println(o.n, n)
        new Order(o.n + n)
      }
    }
    
    val a = new Order(1)
    val b = new Order(2)
    val c = new Order(3)
    
    a :::: b :::: c // 계산 결과: (2,3) (1,5)
    a *** b *** c   // 계산 결과: (2,1) (3,3)

    ::::으로 정의된 메서드는 c.::::(b).::::(a)의 순서로 호출되었고, ***은 a.***(b).***(c)의 순서로 호출되었음을 알 수 있다.

    '스칼라' 카테고리의 다른 글

    [스칼라] 함수와 클로저  (0) 2022.01.31
    [스칼라] 내장 제어 구문  (0) 2022.01.31
    [스칼라] 함수형 객체  (0) 2022.01.30
    [스칼라] 클래스와 객체  (0) 2022.01.30
    [스칼라 입문] PRELUDE꞉ A TASTE OF SCALA 번역  (0) 2022.01.09

    댓글

Designed by Tistory.