스칼라에서는 new 키워드를 사용해 객체를 인스턴스화 할 수 있다.
(즉, 클래스의 인스턴스를 만들 수 있다.)
스칼라에서 객체를 인스턴스화 할 떄, 값과 타입을 파라미터로 넘길 수 있다.
val big = new java.math.BigInteger("12345")
val greetStrings = new Array[String](3)
greetStrings(0) = "Hello"
greetStrings(1) = ", "
greetStrings(2) = "world!\n"
for (i <- 0 to 2)
print(greetStrings(i))
좀 더 명시적으로 타입을 선언하고 싶다면...
val greetStrings: Array[String] = new Array[String](3)
greetStrings은 Array[String]이라는 타입의 값
이 배열을 3이라는 값으로 파라미터화함으로써 길이를 초기화
타입과 값을 가지고 인스턴스화할 때는 먼저 타입을 각 괄호 사이에 지정하고, 값을 괄호 사이에 지정한다.
val 로 선언한 변수는 재할당 할 수 없다.
하지만, 변수가 나타내는 객체는 잠재적으로 변경이 가능하다.
greetStrings에는 다른 변수를 넣을 수는 없지만, greetStrings(0), greetStrings(1), greetStrings(2) 와 같은 Array[String]의 원소는 언제나 변경할 수 있다 즉, 배열자체는 mutable 하다.
val greetStrings = new Array[String](3)
greetStrings.update(0, "Hello")
greetStrings.update(1, ", ")
greetStrings.update(2, "world!\n")
for (i <- 0 to 2)
print(greetStrings.applt(i))
함수형 프로그래밍의 가장 큰 착안점 → 메소드에 부수 효과가 없어야 함.
지금까지 스칼라 배열은 모든 원소의 타입이 같은 객체로 이뤄진 변경가능한 시퀀스였다.
-> 같은 타입의 객체로 이루어진 변경 불가능한 시퀀스를 위해서는 List를 사용할 수 있다.
스칼라의 리스트인 scala.List는 변경 불가능하다는 점에서 자바의 java.util.List 타입과 다르다. (자바의 리스트는 원소를 바꿀 수 있었다.)
val oneTwoThree = List(1, 2, 3)
val oneTwo = List(1, 2)
val threeFour = List(3, 4)
val oneTwoThreeFour = oneTwo ::: threeFour
println(oneTwo + " and " + threeFour + "were not mutated.")
println("Thus, " + oneTwoThreeFour + "is new list.")
//결과
List(1, 2) and List(3, 4) were not mutated.
Thus, List(1, 2, 3, 4) is a new list.
'::' 콘즈(cons) 메소드는 두 리스트를 연결하여 새로운 List를 만든다.
val oneTwoThree = 1 :: 2 :: 3 :: Nil
println(oneTwoThree)
'Nil' 빈 리스트 Nil을 사용하여 새롭게 리스트를 초기화 할 수 있다.
튜플(tuple)은 리스트와 마찬가지로 변경 불가능하지만, 튜플에는 각기 다른 타입의 원소를 넣을 수 있다.
val pair(99, ""Luftballons)
println(pair._1)
println(pair._2)
스칼라의 목적은 프로그래머가 함수형스타일과 명령형스타일의 장점을 모두 취할 수 있도록 돕는 것, 따라서 스칼라 컬렉션 라이브러리에서 변경가능한 컬렉션과 변경 불가능한 컬렉션을 구분
// 명령형 스타일로 함수 선언
// var가 있기 때문에 명령형 스타일
def printArgs(args: Array[String]): Unit = {
var i = 0;
while (i < args.length) {
println(args(i))
i += 1
}
}
// 함수형 스타일로 함수 선언
def printArgs(args: Array[String)): Unit = {
for (arg <- args)
println(arg)
}
// 또는
def printArgs(args: Array[String]: Unit) = {
args.foreach(println)
}
import scala.io.Source // Source 메소드 임포트
// 문자열 길이 계산한다.
def widthOfLength(s: String) = s.length.toString.length
if (args.length > 0) {
val lines = Source.fromFile(args(0)).getLines().toList // toList를 호출해 리스트로 만든다.
val longestLine = lines.reduceLeft( // 최대값 찾는다.
(a, b) => if (a.length > b.length) a else b
)
val maxWidth = widthOfLength(longestLine) // 최대 너비 계산
for (line <- lines) { // 최대 너비에서 현재 라인의 너비를 제외하고 그 만큼의 공백을 삽입
val numSpaces = maxWidth - widthOfLength(line)
val padding = " " * numSpaces
println(padding + line.length + " | " + line)
}
}
else
Console.err.println("Please enter fileName")