Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행하고 있다.


3장

배열

  • 파라미터화(parameterization) : new를 사용해 객체를 인스턴스화 할때에 값과 타입을 파라미터로 전달하는 것
val greetStrings: Array[String] = new Array[String](3)
  • 인스턴스 타입은 타입 파라미터 까지만 포함됨 : (3) 은 제외
val greetStrings = new Array[String](3)
greetStrings(0) = "Hello"
greetStrings(1) = ", "
greetStrings(2) = "World!\n"
for (i <- 0 to 2)
  print(greetStrings(i))
  • 메소드가 파라미터를 하나만 요구하는 경우, 그 메소드를 점(.)과 괄호 없이 호출할 수 있다. 단, 호출 대상 객체가 명시적으로 지정되어 있는 경우에 가능 0 to 2 === (0).to(2)
  • 스칼라는 전통적인 의미의 연산자가 없으므로 연산자 오버로드를 제공하지 않으며, 대신 +, -, *, / 등의 문자를 메소드 이름으로 사용 가능 1 + 2 === (1).+(2)
  • 배열도 평범한 인스턴스 : 변수 뒤에 하나 이상의 값을 괄호로 둘러싸서 호출하면, 스칼라는 변수에 대해 apply 메소드 호출 greetStrings(i) === greetStrings.apply(i)
  • 변수 뒤에 괄호로 둘러싼 인자들이 있는 표현식에 할당을 하면, 스칼라는 update 메소드를 호출 greeStrings(0) = "Hello" === greetStrings.update(0, "Hello")
val numNames = Array("zero", "one", "two")
  • Array의 동반 객체에 정의된 apply라는 팩토리 메소드 호출

리스트

같은 타입의 변경 불가능한 시퀀스

val oneTwo = List(1,2)
val threeFour = List(3,4)
val oneTwoThreeFour = oneTwo ::: threeFour
  • 리스트 자체를 변환하지 않고 새 값을 갖는 리스트를 만든다.
val twoThree = List(2,3)
val oneTwoThree = 1 :: twoThree
  • : 로 이름이 끝나는 메소드는 오른쪽 피연산자에 대해 호출한다.
val oneTwoThree = 1 :: 2 :: 3 :: Nil
  • List() === Nil

리스트 메소드

  • List() / Nill : 빈 리스트
  • List(1,2,3) / 1 :: 2 :: 3 :: Nill : 원소들로 구성된 리스트
  • List(1, 2) ::: List(3, 4) : 두 리스트를 연결한 리스트
  • thrill(2) : thrill 리스트의 세번째 원소
  • thrill.count(s => s.length == 4) : 길이가 4인 것의 갯수
  • thrill.drop(2) : 처음 두 원소를 뺀 리스트
  • thrill.dropRight(2) : 마지막 두 원소를 뺀 리스트
  • thrill.exists(s => s == "until") : "until"이 리스트에 있는지 여부
  • thrill.filter(s => s.length == 4) : 길이가 4인 것들의 리스트
  • thrill.forall(s => s.endsWith("l")) : 모든 원소가 끝이 "l"로 끝나는지 여부
  • thrill.foreach(s => print(s)) : 리스트의 모든 원소에 대해서 print 실행
  • thrill.foreach(print) : 상동
  • thrill.head : 첫번째 원소
  • thrill.init : 마지막 원소 제외한 나머지
  • thrill.isEmpty : 리스트가 비어있는지 여부
  • thrill.last : 마지막 원소
  • thrill.length : 리스트의 길이
  • thrill.map(s => s + "y") : 각 원소 뒤에 "y"를 추가한 리스트
  • thrill.mkString(", ") : 원소들을 ", "로 연결한 문자열
  • thrill.remove(s => s.length == 4) : 길이가 4인 것을 제외한 리스트
  • thrill.reverse : 원소를 역순으로 한 리스트
  • thrill.sort((s, t) => s.charAt(0).toLower < t.charAt(0).toLower) : 알파벳 순서 정렬한 리스트
  • thrill.tail : 첫번째 원소를 제외한 리스트

튜플

다른 타입의 원소들을 갖는 변경 불가능한 시퀀스

val pair = (99, "Luftballons")
println(pair._1) // 99
println(pair._2) // Luftballons
  • apply 메소드는 항상 동일한 타입 객체를 반환하기 때문에 pair(0)과 같이 할 수 없음.
  • 하스켈, ML 등의 영향으로 인덱스가 1부터 시작

집합과 맵

변경가능 / 불가능 모두 제공

변경 불가능 Set

var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear"

변경 가능 Set

import scala.collection.mutable.Set
val movieSet = Set("Hitch", "Poltergeist")
movieSet += "Shrek"

변경 불가능 Map

val romanNumeral = Map(
    1 -> "I", 2 -> "II", 3 -> "III", 4 -> "IV", 5 -> "V"
)
  • -> 메소드를 호출하면 해당 객체를 키로하고 인자를 값으로 하는 원소가 2개인 튜플을 생성

변경 가능 Map

import scala.collection.mutable.Map
val treasureMap = Map[Int, String]()
treasureMap += (1 -> "Go to Island.")

함수형 스타일

  • 코드에 var가 있으면 명령형 스타일, 아니면 함수형 스타일
  • val, 불변객체, 부수 효과 없는 메소드를 먼저 사용해보고, 꼭 필요한 경우에만 var, 가변객체, 부수 효과 있는 메소드를 사용하라

파일

import scala.io.Source
if (args.length > 0) {
    for (line <- Source.fromFile(args(0)).getLines())
        println(line.length + " " + line)
}
else
    Console.err.println("Please enter filename")


+ Recent posts