[코틀린] 코틀린에서 Type을 다루는 방법

J·2023년 3월 20일
1

안드로이드

목록 보기
14/29
post-custom-banner

1. 기본 타입

  • Byte
  • Short
  • Int
  • Long
  • Float
  • Double
  • 부호 없는 정수들

코틀린에서는 선언된 기본 값을 보고 타입을 추론한다.

<Java와 다른 내용>

  • Java : 기본 타입간의 변환은 암시적으로 이루어질 수 있다.
  • Kotlin : 기본 타입간의 변환은 명시적으로 이루어져야 한다.

<Java 버전>

int number1 = 4;
long number2 = number1; //둘이 타입이 다른데도 불구하고 int는 4바이트, long은 8바이트로 long이 더 크므로 들어간 다음에 계산이 된다.
//int 타입의 값이 long 타입으로 암시적으로 변경되었다. Java에서 더 큰 타입으로는 암시적 변경이 됨.
System.out.println(number1 + number2);

<Kotlin 버전>

val number1 = 4
val number2: Long = number1 // Type mismatch
//Kotlin에서는 암시적 타입 변경이 불가능함 -> 어떻게 해야할까?!
println(number1 + number2)

Kotlin에서는 암시적 타입 변경이 불가능하다.

다만, 명시적으로는 가능한데, to변환타입() 을 사용하면 가능하다.

val number1 = 4
val number2: Long = number1.toLong()

println(number1 + number2)

val number1 = 3
val number2 = 5
val result = number1 / number2.toDouble()

println(result)

val number1: Int = 4
val number2: Long = number1.toLong()

println(number1 + number2)

=> 결론적으로 코틀린에서 타입 변환을 하기 위해서는 to변환타입()을 사용해야 한다.

변수가 nullable이라면 적절한 처리가 필요하다.

2. 타입 캐스팅

기본 타입이 아닌 일반 타입은 어떨까?

<Java 코드>

public static void printAgeIfPerson(Object obj) {
  if (obj instanceof Person) {
    Person person = (Person) obj;
    System.out.println(person.getAge());
  }
}
  • instanceof : 변수가 주어진 타입이면 true, 그렇지 않으면 false = 코틀린의 is
  • (타입) : 주어진 변수를 해당 타입으로 변경한다 = 코틀린의 as 타입 (생략 가능함 → 생략하는 기능을 스마트 캐스트라고 함.)

<Kotlin 코드>

fun printAgeIfPerson(obj: Any) {
  if(obj is Person) {
    val person = obj as Person
    println(person.age)
  }
}

<Java 코드 2>

public static void printAgeIfPerson(Object obj) {
  if(obj instanceof Person) {
    System.out.println(((Person) obj).getAge());
  }
}

<Kotlin 코드 2>

fun printAgeIfPerson(obj: Any) {
  if(obj is Person) {
    println(obj.age) //스마트 캐스트
  }
}
  • 스마트 캐스트 : 코틀린 컴파일러가 똑똑하게 자동으로 변환해주는 기능. 스마트 캐스트는 두 가지의 경우에 자동으로 수행되는데, 첫 번째로 변수의 값이 null인지 확인할 때, 두 번째로 is, !is 연산자로 변수 타입을 확인할 때 자동으로 수행된다.

Instanceof의 반대도 존재할까?!

<Java 코드 3>

public static void printAgeIfPerson(Obejct obj) {
  if(!(obj instanceof Person) {
    ...
  }
}

<Kotlin 코드 3>

fun printAgeIfPerson(obj: Any) {
  if(obj !is Person) {
    ...
  }
}

만약 obj에 null이 들어올 수 있다면?!

<Kotlin 코드>

fun main() {
  printAgeIfPerson(null)
}

fun printAgeIfPerson(obj: Any?) {
  val person = obj as? Person
  println(person?.age)
}

value is Type

  • value가 Type이면? true
  • value가 Type이 아니면? false

value !is Type

  • value가 Type이면? false
  • value가 Type이 아니면? true

value as Type

  • value가 Type이면? Type으로 타입 캐스팅
  • value가 Type이 아니면? 예외 발생

value as? Type

  • value가 Type이면? Type으로 타입 캐스팅
  • value가 null이면? null
  • value가 Type이 아니면? null

3. Kotlin의 특이한 타입 3가지

a. Any
b. Unit
c. Nothing

a. Any

Java의 Object 역할. (모든 객체의 최상위 타입)
모든 Primitive Type의 최상의 타입도 Any이다.
Any 자체로는 null을 포함할 수 없어 null을 포함하고 싶다면, Any?로 표현.
Any에 equals / hashCode / toString 존재.

b. Unit

Unit은 Java의 void와 동일한 역할.
(살짝 어려운 내용) void와 다르게 Unit은 그 자체로 타입 인자로 사용 가능하다.
함수형 프로그래밍에서 Unit은 단 하나의 인스턴스만 갖는 타입을 의미. 즉, 코틀린의 Unit은 실제 존재하는 타입이라는 것을 표현.

c. Nothing

Nothing은 함수가 정상적으로 끝나지 않았다는 사실을 표현하는 역할.
무조건 예외를 반환하는 함수 / 무한 루프 함수 등

fun fail(message: String): Nothing {
  throw IllegalArgumentException(message)
}

4. String interpolation / String indexing

<Java 코드>

Person person = new Person("전하윤", 100);
String log = String.format("사람의 이름은 %s이고 나이는 %s세 입니다.", person.getName(), person.getAge());

StringBuilder builder = new StringBuilder();
builder.append("사람의 이름은");
builder.append(person.getName());
builder.appdend("이고 나이는");
builder.append(person.getAge());
builder.append("세 입니다.");

<Kotlin 코드>

val person = Person("전하윤", 100) // Person(name, age) 임.
val log = "사람의 이름은 ${person.name}이고 나이는 ${person.age}세 입니다"

=> ${변수} 를 사용하면 값이 들어간다.
=> 이것도 javascript와 유사하다. 오…

예제

fun main() {
  val person = Person("최태현", 100) // Person(name, age) 임.
  System.out.println(String.format("이름 : %s", person.name))
  
  println("이름 : ${person.name}")
}

Kotlin 코드 2

val name = "최태현"
val age = 100
val log = "사람의 이름: $name 나이: $age"

=> $변수 를 사용할 수도 있다.
=> javascript와 유사 22…

예제 2

fun main() {
  val name = "최태현"
  
  println("이름 : $name")
}

TIP

변수 이름만 사용하더라도 ${변수}를 사용하는 것이

01) 가독성
02) 일괄 변환
03) 정규식 활용

측면에서 좋다.

코틀린에서는 여러 줄의 문자열을 작성 시, 큰 따옴표(“) 3개를 작성하면 더 편하게 작성 가능하다.

fun main() {
  val name = "최태현"
  var str = """
    ABC
    EFG
    ${name}
  """.trimIndent()
  println(str)
}

<자바 코드>

String str = "ABCDE";
char ch = str.charAt(1);

=> Java에서 문자열의 특정 문자 가져오기

<코틀린 코드>

val str = "ABCDE"
val ch = str[1]

=> Kotlin에서 문자열의 특정 문자 가져오기

※ 코틀린에서 Type을 다루는 방법 (정리) ※

  • 코틀린의 변수는 초기값을 보고 타입을 추론하며, 기본 타입들 간의 변환은 명시적으로 이루어진다.
  • 코틀린에서는 is, !is, as, as? 를 이용해 타입을 확인하고 캐스팅한다.
  • 코틀린의 Any는 Java의 Object와 같은 최상위 타입이다.
  • 코틀린의 Unit은 Java의 void와 동일하다.
  • 코틀린에 있는 Nothing은 정상적으로 끝나지 않은 함수의 반환을 의미한다.
  • 문자열을 가공할 때 ${변수}와 “““ “““ 를 사용하면 깔끔한 코딩이 가능하다.
  • 문자열에서 문자를 가져올 때 Java의 배열처럼 []를 사용한다.
post-custom-banner

0개의 댓글