Enum class 이넘클래스
enumeration을 줄인 enum 클래스는 미리 정의된 상수들로 이뤄진 제한된 집합을 표현하는 특별한 클래스다. 아래와 같이 쓰면 변수를 쭉 선언한 상태보다 가독성과 연관성을 한눈에 알아보기 쉬워지고 ‘타입에 의한 열거형’ 이기 때문에 상수의 값이 같더라도 타입까지 체크해주기 때문에 좀 더 안전하게 변수 사용이 가능해진다.
- 컴파일 시점 상수이므로 이넘 값을 쓸 때는 보통 대문자를 사용한다.
- 객체와 마찬가지로 전역 상수로 사용할 수 없는 위치에서는 이넘을 정의할수없다.
when식에서 이넘 클래스를 사용하는 경우
when 식에서 모든 이넘 상수를 다룬 경우에는 else 가지를 생략해도 된다. 이렇게 사용하게 되면 새로운 enum 값을 추가하는 경우에 깨질 수 있는 코드가 생기는 일을 방지 할 수 있다.
- else 를 안써도 되기 때문.
커스텀 멤버가 있는 이넘 정의하기
다른 클래스와 마찬가지로 이넘클래스도 멤버를 포함할 수 있다. 이넘 클래스도 함수, 프로퍼, 주생성자와 부생성자, 초기화 블록, 내부 클래스/내포된 클래스, 체 등을 포함할수 있다.
- 위와 같이 포함된 요소들은 수 뒤에 와야하고 상수 목록을 세미콜론(;)으로 끝내야한다.
- 생성자가 있으면 정의 뒤에도 적절한 생성자 호출을 추가해야한다.
MONDAY{ fun startWork() = println(“HELLO”)}
- 위와 같은 본문이 포함될수있지만 외부에서 접근할수없다.
이넘 클래스의 공통 멤버 사용하기
코틀린의 모든 이넘 클래스는 kotlin.Enum클래스의 하위타입니다. 모든 이넘 값에는 ordinal과 name이라는 한 쌍의 프로퍼티가 들어있다.
- ordinal: 순서에 따른 인덱스
- name: 이넘값의 이름
Direction.WEST == Direction.NORTH
와 같이 위치에 따른 비교도 가능하다.
- valueOf(): 이넘 값의 이름을 문자열로 넘기면 그에 따른 이넘값을 돌려준다.
- values(): 정의된 순서대로 모든 이넘 값이 들어있는 배열을 돌려준다.
Direction.values() // [NORTH, SOUTH, WEST, EAST]
- 최상의 메서드인 enumValues()와 enumValueOf()를 사용할수도있다.
데이터 클래스
코틀린은 데이터를 저장하기 위한 목적으로 주로 쓰이는 클래스를 선언하는 기능을 제공한다.
- 컴파일러가 동등성을 비교하거나 String으로 변환하는 등의 기본 연산에 대한 구현을 자동으로 생성해준다.
- 구조 분해 선언을 활용할 수도 있다.
구조분해: 구조분해를 사용하면 클래스의 프로퍼티를 간단한 한가지 언어 구성요소를 사용해 여러번수에 나눠 넣을 수 있다.
class Person(val firstName: String, val familyName: String, val age: Int)
비교를 하게 되면 클래스는 주소를 가르키기 때문에 주소값을 비교하게 되는데 값을 비교하기위해선 보통 equals(), hashCode() 메서드를 구현해 비교를 하는데, 데이터클래스는 이런 메서드를 자동으로 생성해준다.
copy():
모든 데이터 클래스는 암시적으로 copy()함수를 제공한다. 현재 인스턴스를 복사하면서 몇몇 프로퍼티를 변경 할 수 있다. 이를 쓰게 되면 불면 데이터 구조를 더 쉽게 사용하도록 해준다.pair / triplet:
코틀린 표준 라이브러리엔 두가지 범용 데이터 클래스가 들어있다, 하지만 가독성을 위해 커스텀 클래스를 사용하는편이 낫다.
구조 분해 선언
괄호로 감싼 식별자 목록으로 여러 변수를 한꺼번에 정의할 수 있게 해주는 일반화된 지역 변수선언 구문이다.
위의 코드는 인스턴스의 각 프로퍼티를 추출한다음 활용하고 있다. 하지만 이는 데이터 클래스이므로 구조분해선언을 사용하면 간결하게 사용 가능하다.
val (firstName, familyName, age) = person
- 매핑의 위치는 프로퍼티의 위치에 따라 결정되며 이름에 따라 결정되지 않는다.
- 선언 전체는 타입이 없다. 타입을 표기할수없다.
- 데이터 클래스의 수보다 적은 수의 변수가 들어갈 수 도 있지만 이런 경우, 뒷부분의 프로퍼티는 추출되지 않는다.
val (firstName, familyName) = Person(“John”, “Doe”, 25) //John, Doe
- 파라미터내에서 사용하지 않는 부분을
_
로 표기할수있다. - val / var 지정은 모든 부분에 적용된다. 둘을 섞어서 정의 할 수 없다.
인라인클래스 (값클래스)
인라인클래스는 새로운 타입을 안전하고 최적화된 형식으로 정의하는 방법이다. 보통 함수형 인자를 받아 함수에서 실행시킬때나 건내줄때 인라인을 쓰게 되면 성능적으로 많이 개선이 된다.
런타임 클래스 인스턴스는 별도의 래퍼객체를 생성하지않고 프로퍼티의 값으로 표현된다.그래서 인라인이라는 이름이 붙여졌다.
인라인클래스 정의하기
value class
를 class 앞에 붙여야한다.- 주생성자에는 불변 프로퍼티를 하나만 선언해야한다.
- 인라인 클래서에도 자체 함수나 프로퍼티를 포함할 수 있지만 프로퍼티는 상태를 포함할수없다. (lateinit, lazy,delegated 사용 불가)
- var프로퍼티를 정의할 순 있지만 내부에서 가변 상태가 없기때문에 의미가 없다.
- 초기화 블록을 쓸 수 없다.
- 속성들이 backing 필드를 가질 수 없다.
부호없는 정수
부호없는 값을 표현하려면 U접두사를 붙인다.
- 부호가 있는 타입과 없는 타입은 서로 호환되지 않는다.
- 부호가 있는 타입과 부호가 없는 타입의 값을 toXXX()를 통해 반대 타입으로 변환 할 수 있다.
- 부호가 없는 값에 대해 증가, 감소, 복합 대입 연산자를 쓸 수 있다.