콘텐츠로 이동

2023 02 28

2023-02-28

Scala at Light Speed

참고: https://www.youtube.com/watch?v=-8V6bMjThNo&list=PLmtsMNDRU0BxryRX4wiwrTZ661xcp6VPM

Basics

  • extends App
    • object Basics extends App
    • App 상속받으면 Play 버튼으로 Run 돌릴 수 있음
  • String & String operation
    • 스칼라 concat, interpolation 지원
      val aString = "I Love Scala"
      val aComposedString = "I" + " " + "love" + " " + "Scala"
      val anInterpolatedString = s"The meaning of life is $meaningOfLife" // s"$" 감성으로 변수 넣자
      
  • Scala is an Expression
    • 함수형으로 표현을 쓰는게 스칼라를 스칼라처럼 쓰는 방법
    • 스칼라는 싹다 expression이야
    • 표현: 특정한 행위가 single value로 축약될 수 있다
  • Defining a function
    • 파라미터, 리턴 타입 써서 함수를 정의해보자
      def myFunction(x: Int, y: String): String = y + " " + x
      
  • Recursion >> Loop
    • Loop
      • for/while 같은 명령형 방식의 코딩은 변할 수 있는 변수를 컨트롤하면서 로직이 진행됨
      • 불변이 아니다보니까 버그로 이어질 수 있음
      • 복잡한 데이터 구조일 수록 더 그럼
    • Recursion
      • 함수형 프로그래밍 테크닉
      • 작은 문제로 나누어서 하나씩 해결하는 감성
      • mutable state에서 자유롭다
      • test, debug 쉬워짐
      • functional nature!

Object-Oriented

  • Class & Instance
    • define fields
    • define methods
      class Animal {
        val age: Int = 0
        def eat(): Unit = println("I'm eating")
      }
      
  • 상속
    • Constructor argument에 val을 붙여주면, 해당 argument는 필드로 승격됨
      class Animal {
        val age: Int = 0
        def eat(): Unit = println("I'm eating")
      }
      
      class Dog(val name: String) extends Animal
      
      val aDog = new Dog("Lassie")
      aDog.eat()
      
      // 당연히 다형성 지원
      val aDeclaredAnimal: Animal = new Dog("Hachi")
      aDeclaredAnimal.eat()
      
  • 추상 클래스
    • 자바와 동일
    • 시그니쳐만 써두자
      abstract class WalkingAnimal {
        val hasLegs = true
        def walk(): Unit
      }
      
  • 트래잇
    • 자바의 인터페이스와 동일
    • 싹다 미완성
      trait Carnivore {
        def eat(animal: Animal): Unit
      }
      
  • 다중상속?
    • 클래스 상속은 하나만, 트레잇은 여러개 상속 가능 (자바와 동일)
      abstract class WalkingAnimal {
        val hasLegs = true
        def walk(): Unit
      }
      
      trait Carnivore {
        def eat(animal: Animal): Unit
      }
      
      trait Philosopher {
        def ?!(thought: String): Unit
      }
      
      class Crocodile extends Animal with Carnivore with Philosopher {
        override def eat(animal: Animal): Unit = println("I am eating")
        override def ?!(thought: String): Unit = println(s"I was thinking $thought")
      }
      
  • 메서드 실행
    • 그냥 객체에서 함수 실행하듯 할 수 있고,
    • 놀랍게도 아규먼트가 하나라면 이런것도 가능
      val aDog = new Dog
      val aCroc = new Crocodile
      aCroc eat aDog
      aCroc ?! "think!"
      
  • 익명 클래스
    • 인터페이스를 상속받은 클래스를 만들고, 할당하는게 아니라
    • 딱히 이름을 만들지 않고 그냥 trait에 new 때려버리면 익명 클래스 만들어서 컴파일러가 할당해줌
      val dinosaur = new Carnivore {
        override def eat(animal: Animal): Unit = println("Eat All!")
      }
      
  • 싱글턴 object
    • 딱 하나만 만들어버리는 싱글턴 객체도 만들 수 있어
    • static을 생각하라고 하는데... 싱글턴 패턴 같지 않을까 싶기도 해
    • class와 동일한 이름의 object가 있으면 이를 companion이라고 하는데
      • companion의 경우 서로의 필드/메서드에 접근할 수 있다고 함
        object MySingleton {
          val myVal = 333
          def myMethod(): Int = 333333
          def apply(x: Int): Int = x + 1 // 요게 조금 독특
        }
        
        MySingleton.myMethod()
        MySingleton.apply(60) 
        MySingleton(60) // 위에꺼랑 동일. apply 했다고 생각
        
  • Case Class
    • equals & hashcode (VO와 같다)
    • serialization (직렬화 할 때 많이 쓰이는 거 아닐까 싶음)
    • companion with apply (apply 함수를 통해 new를 생략할 수 있도록 지원하는 듯)
    • 패턴 매칭에도 많이 쓰임
      case class Person(name: String, age: Int)
      val joel = Person("Joel", 25)
      
  • 제네릭
    • 자바 제네릭과 비슷
    • <> 대신 [] 사용
  • 스칼라 객체지향 TIP
    1. Scala의 객체는 싹 다 불변!
    2. App 클래스안에 main 함수있어서 이거 상속받으면 psvm과 동일

Scala Apply

참고: https://hamait.tistory.com/651