변수와 조건절
1. val, var
- val : 불변(Immutable), 읽기만 허용. ( 값 (Value)의 약자)
- var : 가변(Mutable), 값의 읽기, 쓰기가 모두 허용. ( 변수 (Variable)의 약자)
2. when {}, when(x) {}
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
}
when (x) {
0,1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
else -> print("none of the above")
fun hasPrifix(x: Any) = when(x) {
is String -> x.startWith("prefix")
else -> false
}
fun Request.getBody() =
when (val response = executeRequest()) {
is Success -> response.body
is HttpError -> throw HttpException(response.status)
}
}
3. elvis 연산자(?:)
?:
의 왼쪽 객체가 Non-null이면 그 객체의 값이 리턴되고, null이라면 오른쪽 (그다음) 값을 리턴한다.
- null일 경우
Default값
, throw Exception
, LOG 남기기, Boolean값(False)
값 주입 등으로 이용할 수 있다.
4. safe call (?.)
str?.length
: str 객체가 null일 때 null을 리턴,
- null이 아닐 때
str.length
리턴
-> nullable한 변수를 검사해서 null이면 NullPointerException이 발생하지 않고 그대로 null 출력
5. non-null 단정자 (!!.)
- 변수에 할당된 값이 null이 아님을 단정하므로 null검사 없이 컴파일함
- 만약 null이 사용되었을 경우 NullPointerException 발생
데이터 클래스
1. data class, copy
- 데이터 클래스(Data class)는 데이터 보관 목적으로 만든 클래스를 말한다.
데이터 클래스는 프로퍼티에 대한 toString()
, hashCode()
, equals()
, copy()
메소드를 자동으로 만들어준다.
- copy()는 객체의 복사본을 만들어 리턴한다. 리턴되는 객체는 얕은 복사 (swallow copy)로 생성된다.
copy()의 인자로 생성자에 정의된 프로퍼티를 넘길 수 있으며, 그 프로퍼티의 값만 변경되고 나머지 값은 동일한 객체가 생성된다.
val site1 = Site("kotlinlang.com",
"Kotlin New Features (1)")
val site2 = site1.copy(title = "Kotlin New Features (2)")
Site(url=kotlinlang.com, title=Kotlin New Features (1))
Site(url=kotlinlang.com, title=Kotlin New Features (2))
예외처리
1. throws, exception
- 자바에서는 throws IOException을 붙여서 예외를 명시적으로 처리해야하는데, 코틀린에서는 함수가 던지는 예외를 잡아내도 되고, 잡아내지 않아도 됨.
- IOException이 체크 예외이기 때문에 자바는 명시적으로 체크예외를 표현해야 한다.
- 체크예외 / 언체크 예외
- 체크예외 : Exception 클래스의 서브클래스이면서 RuntimeException 클래스를 상속하지 않은것들
- 언체크예외 :
RuntimeException
을 상속한 클래스
-> 체크예외가 발생할 수 있는 메소드를 사용할 경우 반드시 예외를 처리하는 코드를 함께 작성해야한다.
-> 사용할 메소드가 체크예외를 던진다면 이를 catch문으로 잡든지, 아니면 throws를 정의해서 메소드 밖으로 던져야한다. 아니면 컴파일에러가 발생.
📌 반면, 언체크 예외의 경우 명시적인 예외처리를 강제하지 않기때문에 언체크 예외라고 불리며, 보통 RuntimeException이라고 부른다.
-> 코틀린은 체크예외와 언체크 예외를 구별하지 않는다.!! 🙈
2. runCatching, result
- runCatching 블록안에서 성공/실패 여부가 나오면, 그 값을 캡슐화된
Result<T>
형태로 리턴한다.
val colorName: Result<String> = runCatching {
when (color) {
Color.BLUE -> "파란색"
Color.RED -> "빨간색"
Color.YELLOW -> "노란색"
Color.ARMARNTH -> throw Error("처음 들어보는 색")
}
}.onSuccess { it:String ->
}.onFailure { it:Throwable ->
}
확장 함수
1. extension
- 코틀린은 클래스를 상속하거나 Decorator같은 디자인패턴을 사용하지않고도 새로운 기능으로 클래스를 확장할 수 있다.
- 예를 들어 수정할 수 없는 타사 라이브러리(Third-party library)의 클래스에 새로운 함수를 작성할 수 있다.
-> 이런 함수는 원래 클래스의 메소드인 것처럼 일반적인 방식으로 호출할 수 있다. : 확장함수(Extension)
-> 기존 클래스에 대한 새로운 속성을 정의할 수 있는 확장속성(Properties)도 있다.
- 확장 함수을 선언하려면 확장되는 유형을 참조하는 수신 타입(receiver type, 확장 대상이 되는 클래스)을 이름 앞에 접두사로 붙인다.
fun 수신타입.함수명(매개변수): 반환타입 { 구현부 }
- 확장함수 내부의
this
는 수신객체에 해당!!
2. let, run, apply
- 범위지정함수 (Scope function)는 특정 객체에 대한 작업을 블록안에 넣어 실행할 수 있도록 하는 함수.
블록은 특정 객체에 대해 할 작업의 범위가 되며, 따라서 범위 지정 함수라 부른다.
- 코틀린에서는 let, run, apply, also, with 총 5가지를 지원한다.
응답 처리
1. generic(<T: ResponseData>)
- 타입 파라미터 제약. : 클래스나 함수에 사용할 수 있는 타입 파라미터를 제한하는 기능
- 예를 들어 List에 속한 모든 원소의 합을 구하는
sum
함수에는 List<Int
>, List<Double
>에 그 함수를 적용할 수 있지만 List<String
>등 에는 사용할 수 없다.
즉, sum 함수가 타입 파라미터로 숫자 타입만을 허용하게 정의해뒀기 때문이다.
- 타입 파라미터를 제한하려면, 타입 파라미터 명 뒤에 콜론
(:)
을 표시하고 그 뒤에 타입범주를 명시하면 된다.
- extends 같은 개념이다.
2. response, success, wrong
추가
1. 깊은 복사, 얕은 복사
-
얕은 복사 : 주소값 자체를 복사.
- 복사된 객체의 인스턴스는 원본 객체의 인스턴스와 같은 메모리 주소를 참조한다.
-> 복사된 객체의 값이 변경되면 원본 객체의 값도 변경된다.
-
깊은 복사 : 새로운 메모리 공간에 객체의 모든 값을 복사.
- 원본 객체는 그대로 두고, 새로운 메모리 공간에 원본 객체의 값들을 모두 복사
-> 복사된 객체가 변경돼도, 원본 객체는 영향X
-
얕은 복사의 문제점?
- 복사된 객체가 변경돼도 원본 객체의 값이 변경된다는 문제점!
- 기본적으로
=
를 사용하여 얕은복사 수행가능
val car = Car("car")
val copyCar = car
-
깊은 복사
- data class의
copy()
사용 (기본 클래스의 경우 copy()를 오버라이딩해서 직접 구현 후 사용)
val car = Car("car")
val copyCar = car.copy()
-
코틀린 Collection의 방어적 복사
- Collection의 깊은 복사를 하는 방법은 대표적으로 일급 컬렉션을 만들어서 방어적 복사를 구현해주는 것.
- 방어적 복사?
생성자로 받은 가변 데이터들을 외부에서 변경하는 것을 막기위해 복사본을 이용
2. companion object
- 자바에 static 변수, 메서드가 존재하듯 코틀린에서도 정적변수와 함수가 존재한다.
- 클래스 내부에서 companion object로 감싸서 선언한 변수는, 전역변수처럼 그냥 사용할 수 있다.
반면, 클래스 내부에 그냥 선언된 변수는 해당 클래스를 인스턴스화한 객체를 통해서만 접근할 수 있다.
-> 컴파일 시에 각각 필요한 영역들을 할당받게 되는데, Companion object로 선언한 변수는 클래스 영역에 위치하고, 그냥 선언된 변수는 클래스 내부에 위치하기 때문이다.
출처
큰 도움이 되었습니다, 감사합니다.