[Scala] 스칼라 기본 문법 정리

smlee·2023년 8월 7일
0

Scala

목록 보기
2/37
post-thumbnail

이 글은 Programming in Scala 4/e를 읽고 정리한 글입니다.

변수 정의하기

Scala에서 변수를 정의하는 방법에는 2개가 있다. 바로 val 키워드와 var 키워드이다. Scala는 타입 추론이 가능하므로 변수를 선언할 때 타입을 명시하지 않아도 된다.

val msg:String = "Hello World!"
val msg2 = "Hello World!"

Scala의 타입 추론 덕에 msg와 msg2는 모두 String 타입으로 선언되었다. 물론, 타입 명시를 반드시 해야하는 경우도 있지만 대부분의 경우 스칼라가 타입 추론을 하도록 놔두어도 된다.

var

var 키워드는 variable의 준말이다. variable의 뜻처럼 var는 변수, 즉 변하는 수이다. 즉, 재할당이 가능한 키워드이다.

val

val 키워드는 value의 준말이다. val은 자바의 final 변수와 유사하다. 즉, 일단 초기화하고 나면 val은 다시 할당할 수 없다. 함수형 프로그래밍을 지향하는 Scala는 var보다는 val 사용을 권장한다.

함수 정의하기

함수의 정의는 def로 시작한다. 그 후, 함수명이 온다. 그리고 그 뒤의 괄호에는 파라미터들이 콤마(,)로 구분되어 들어온다. 스칼라가 함수의 파라미터 타입을 추론하지 않기 때문에, 함수의 파라미터는 반드시 타입 지정을 해야한다. 그리고, 결과 타입을 지정해야 한다. 결과 타입 뒤에는 등호와 중괄호가 오고, 중괄호 안에는 함수의 본문이 들어간다.

def max(a: Int, b:Int): Int = {
	if(a>b) a
    else b
}

위는 간단한 예제 함수이다. def 키워드 뒤에 함수명인 max가 왔다. 그리고 그 뒤에 있는 소괄호에는 함수에서 사용할 파라미터 목록과 각각 파라미터들의 타입이 명시되었다. 그리고, 리턴 타입과 내용이 명시된다.

이때, 주의해야 할 점은 리턴 값이 없으면 Unit을 사용해야 한다는 점이다. Unit은 다른 언어의 void와 같다고 생각하면 된다. 함수 결과 타입 역시 Scala에서 타입 추론이 가능하지만, 재귀 함수의 경우 결과 타입을 반드시 명시해야 한다.

Array, List, Tuple 정의하기

Scala에서는 new 키워드를 사용하여 객체를 인스턴스화할 수 있다. 스칼라에서 객체를 인스턴스화할 때, 값과 타입을 파라미터화한다. 인스턴스를 타입으로 파라미터화할 때는 하나 이상의 타입을 각괄호([]) 사이에 지정한다.

파라미터화(parameterization)
인스턴스를 생성할 때 그 인스턴스를 설정(configuration)한다는 뜻

(1) Array

val		greetingStrings = new Array[String](3)

greetingStrings(0) = "Hello"
greetingStrings(1) = " "
greetingStrings(2) = "World!\n"

위는 배열을 정의하는 방법 중 하나이다. Array[String]으로 타입을 지정하였고, 3이라는 값으로 파라미터화하여 길이를 초기화한 것을 볼 수 있다. 하지만 위의 방법은 Scala에서 지향하는 배열 선언 방법은 아니다.

val		greetingStrings = Array("Hello", " ", "World!\n")

위와 같이 선언하는 것이 Scala에서 지향하는 방식이다.
위의 방식은 apply라는 이름의 팩토리 메서드(factory method)를 호출한다. 이 메서드는 새로운 배열을 만들어서 반환한다.

팩토리 메서드 (factory method)
인스턴스화하여 제공하는 메서드

(2) List

Scala는 함수형 프로그래밍이므로 하나의 메서드에 side effect가 없어야 한다. Array는 인스턴스화 후 길이를 변경할 수 없지만, 원소는 바꿀 수 있다. 하지만, 스칼라의 리스트인 scala.List는 변경 불가능하다는 점에서 자바의 Java.util.List 타입과 다르다.


위는 스칼라 인터프리터로 val배열 원소를 작성하고 원소를 변경한 코드이다.
val로 선언을 했지만, 배열의 0번 인덱스의 원소가 업데이트된 것을 확인할 수 있다.

val		numberList = List(1, 2, 3)

위는 리스트의 선언 방법이다. Scala는 numberList라는 배열을 만들며 List[Int]로 초기화한다. List가 변경 불가능하므로 java의 문자열과 비슷하게 동작한다. 즉, 리스트의 내용을 변경하는 것 같아 보이는 메서드를 호출하면, 리스트 자체를 변경하지 않고 새 값을 같는 리스트를 새로 만들어서 반환하는 것이다.

위 이미지는 List를 선언한 것이다. updated를 했음에도 numberList의 원소들이 변경되지 않았다. 이 부분에서 리스트는 원소를 변경할 수 없음을 알 수 있다.

(3) Tuple

튜플은 리스트와 마찬가지로 변경 불가능하지만 튜플에는 각기 다른 타입의 원소를 넣을 수 있다. 즉, 리스트와 달리, 튜플 내의 데이터 타입이 같을 필요가 없다는 것이다. 또한, 튜플은 인덱스가 1부터 시작하며, 각 원소에 접근하려면 ._ 다음에 읽을 인덱스를 넣는다.

val		pair = (99, "Scala")
println(pair._1) // 출력값 : 99
println(pair._2) // 출력값 : Scala

위와 같이 튜플을 정의할 수 있는데, 이렇게 된다면 튜플의 타입은 Tuple[Int,String]이 되는 것이다. 스칼라 컴파일러나 인터프리터는 이러한 튜플의 타입을 추론하고 지정해준다.

📚 Reference

0개의 댓글