배열이 무엇일까. 배열은 여러 개의 값을 담을 수 있는 대표적인 자료형이다. 코틀린에서는 배열보다는 컬렉션이라는 동적배열을 더 많이 사용한다고 하는데, 오늘은 그래도 알아두면 절대 나쁠 일 없는 배열에 대해 알아보았다.
배열 하나 알아보려고 했는데 어쩌다 여기까지 왔을까. 죄가 있다면 나의 무지함이 죄겠지… 이전에 코틀린의 모든 자료형은 참조형이라는 말을 한 적이 있다. — 참고 그 때 잠깐 나왔던 기본형(직접 값을 가지고 있다.)이 바로 원시 타입이 되겠다.
그렇다면 래퍼 타입은?
원시 타입에 대해 참조 타입이 필요할 때 원시 타입 값을 감싸서 사용하는데, 이걸 래퍼 타입이라 한다.
알쓸코잡(알아두면 쓸모있는 코딩 잡학 사전이라는 뜻^^~)
원시 타입을 래퍼 타입으로 감싸는 것을 Boxing, 그 반대를 UnBoxing이라고 한다.
그렇지만 모든 타입이 참조형인 코틀린에서는 원시타입과 래퍼타입을 구분하지 않는다고 한다.
코틀린에는 배열을 선언하는 다양한 방법이 있다.
// 배열 클래스의 생성자 사용
Array(길이)
Array(길이) { 초기값 }
자료형Array(길이)
// 함수 사용
arrayOf(원소들)
자료형ArrayOf(원소들)
// Null 값이 들어간 배열
arrayOfNulls(길이)
우리는 (일단 나는) 자료형을 붙이고 안붙이고의 차이가 뭔지 궁금할 것이다. 여기서 배열 선언 방법에 대해 알아보기 전에 래퍼 타입을 알아보게 된 이유가 나오게 된다. 자료형을 붙이면 내부적으로 자바의 원시 타입 배열이 선언되고, 안붙일 경우 래퍼 타입 배열이 선언된다! 사실 더 깊게 알아가보면 성능을 위해 내부적으로 이렇게 한다고 하는데.. 나중에 더 알아보도록 해야겠다.
보통 배열을 선언할 때, int[2]
이런 식으로 하다보니 코틀린에서는 어떻게 2차원으로 배열을 만들어야 되는지 궁금했다. 특이하게도 “초기값”에 배열을 선언해서 만든다고 한다. 정말 알아보지 않으면 영원히 모를 뻔했다..
Array(길이) { Array(길이) }
알아도 알아도 끝이 없는 녀석이 클래스인 것 같다. 모르고 썼던 아이들이 사실은 클래스의 메서드였다.. 클래스로부터 만들어진 객체였다..는 경험이 나는 정말 많기 때문이다. 그래서 정말 이번에는 클래스를 세포 단위로 뜯어먹어보..려고 했지만 조금 방대해서 찍먹만 해보려고 한다.
여러 번 공부했고, 여러 번 정리해봤다. 이제 눈 감고도 나오는 지경에 이른 그 문장.. “클래스는 설계도다”! 조금 더 사전에 나올 것 같은 말들로 바꿔말하면, 그룹화할 수 있는 변수와 함수들의 모음이라고 할 수 있겠다.
의미를 알았다면 구조를 알아봐야겠지. 사실 위에서 말했다싶이 클래스는 변수와 함수로 이루어져있다. 다르게 말하면 클래스 이름, 헤더, 바디로 구성되는데, 이 중에서 헤더와 바디는 생략이 가능하다. 여기서 바디는 중괄호 내부의 요소들을 말하고, 헤더는 생성자나 매개변수 등을 말한다.
class MyClass {
var myVar // 멤버 변수 (프로퍼티)
fun myFun() { ... } // 멤버 함수 (메서드)
}
class MySecondClass // 도 가능!
생성자는 인스턴스 초기화 메서드를 말한다. 코틀린의 클래스는 하나의 프라이머리 생성자, 여러 개의 세컨더리 생성자를 가질 수 있다.
프라이머리하면 무엇이 생각나는가? 가수..가 아니라 “주요한, 기본의”가 생각날 것이다. 프라이머리 생성자는 의미에 걸맞게 클래스 이름 바로 옆(클래스 헤더)에 기술한다.
// 생성자에 접근 제한자나 다른 옵션이 없다면 constructor 키워드 생략 가능
class MyClass constructor(myValue: Int) {
// 초기화 작업이 필요하지 않다면 생략 가능
init {
// 생성자가 호출되면 init 블록의 코드가 실행된다.
// myValue(생성자를 통해 넘어온 파라미터)에 접근 가능!
}
// init 외부에서 myValue에 접근하고 싶다면,
// constructor(val myValue: Int) 와 같이
// val 키워드를 붙여주자.
}
var
vs.val
vs.const
var
는 가변, val
은 불변을 나타낸다. 이렇게만 이해하면 상수를 나타내는 const
와 val
의 차이가 없는 것 같지만, 초기화 시점에서의 차이가 있다고 한다.
const
: 변수의 초기화 값이 컴파일 시점에 결정된다.val
: 변수의 초기화 값이 런타임에 결정된다.프라이머리 생성자는 클래스 이름 옆에 작성했다면, 세컨더리 생성자는 클래스 스코프 안(중괄호 내부)에 작성할 수 있다. 클래스는 여러 개의 세컨더리 생성자를 가질 수 있기 때문에 파라미터의 개수나 타입이 다르다면 중복해서 만들 수 있다.
class MyClass {
// constructor 키워드를 사용해 작성한다.
constructor (myValue: Int) { ... }
constructor (myValue: String) { ... }
}
생성자를 아예 작성하지 않으면 어떻게 될까? 자바에서처럼 기본 생성자라는 것이 코틀린의 클래스에도 존재한다. 생성자를 작성하지 않아도 파라미터가 없는 프라이머리 생성자가 하나 있는 것과 동일하다고 한다. 따라서, 다음과 같은 코드가 가능하다.
class MyClass {
init {
// 프라이머리 생성자가 없더라도 초기화가 필요하다면 이곳에 작성하면 된다!
}
}