Kotlin 공부

0

Kotlin

목록 보기
1/32
post-thumbnail
post-custom-banner

변수와 조건절

1. val, var

  • val : 불변(Immutable), 읽기만 허용. ( (Value)의 약자)
    • var : 가변(Mutable), 값의 읽기, 쓰기가 모두 허용. ( 변수 (Variable)의 약자)

2. when {}, when(x) {}

  • Switch와 유사하게 사용된다.
// 일반적인 방법
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")  // x가 1~ 10 이내(in)일 때
    in validNumbers -> print("x is valid")  // x가 10~20이 외 (!in)일 때
	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()) { // x를 식으로 대입하기!!
    	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 ->
    //실패시만 실행 (try - catch문의 catch와 유사)
}

확장 함수

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로 선언한 변수는 클래스 영역에 위치하고, 그냥 선언된 변수는 클래스 내부에 위치하기 때문이다.

출처

profile
백엔드를 공부하고 있습니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 8월 16일

큰 도움이 되었습니다, 감사합니다.

답글 달기