Kotlin 기본 문법 - 유용한 기능

2024. 6. 11. 20:37[Android] Kotlin 기본 문법

# 자료형의 변환

1) 일반 자료형 간 변환

- 숫자 자료형끼리: to자료형() 메서드 활용 가능

- 문자열을 숫자로 변환 시: 별도의 메서드 필요 (예: Integer.parseInt(strNum5)

	var num1 = 20
    var num2 = 30.2

    var num3 = num2.toInt()
    var num4 = num1.toDouble()

    var strNum5 = "10"
    var strNum6 = "10.21"

    var num5 = Integer.parseInt(strNum5)
    var num6 = strNum6.toDouble()

    println("num3: $num3")
    println("num4: $num4")
    println("num5: $num5")
    println("num6: $num6")

 

 2) 객체 자료형 간 변환

- 상속관계 사이에서 가능

- 업캐스팅: 서브클래스를 수퍼클래스의 자료형으로 객체 생성

fun main() {
    println("몇 마리를 생성하시겠습니까?")
    var count = readLine()!!.toInt()
    // birds 클래스에는 Bird만 들어갈 수 있다고 자료형을 제한해놓음
    var birds = mutableListOf<Bird>()

    for(idx in 0..count-1) {
        println("조류의 이름을 입력해주세요")
        var name = readLine()!!

		// 업캐스팅, as Bird(Bird로 취급해 birds안에 들어가도록 허용)를 통해 업캐스팅(생략 가능)
        birds.add(Sparrow(name) as Bird)
    }
    println("============조류 생성완료============")
    for(bird in birds) {
        bird.fly()
    }
}

open class Bird(name: String) {
    var name: String

    init {
        this.name = name
    }

    fun fly() {
        println("${name}이름의 조류가 날아요~")
    }
}

class Sparrow(name: String): Bird(name) {

}

 

- 다운캐스팅: 수퍼클래스를 서브클래스의 자료형으로 객체 생성

fun main() {
    println("몇 마리를 생성하시겠습니까?")
    var count = readLine()!!.toInt()
    var birds = mutableListOf<Bird>()

    for(idx in 0..count-1) {
        println("조류의 이름을 입력해주세요")
        var name = readLine()!!

        birds.add(Sparrow(name) as Bird)
    }
    println("============조류 생성완료============")
    for(bird in birds) {
        bird.fly()
    }
    // 다운캐스팅 오류
    // Sparrow는 Bird가 가져야할 정보를 모두 가지고 있지 않기 때문임(Bird가 더 큰 개념)
//    var s1:Sparrow = birds.get(0)
}

open class Bird(name: String) {
    var name: String

    init {
        this.name = name
    }

    fun fly() {
        println("${name}이름의 조류가 날아요~")
    }
}

class Sparrow(name: String): Bird(name) {

}

 

# 자료형의 확인

- is자료형() 함수를 통해 확인 가능  

 

# 여러 인스턴스를 리턴하는 방법

- 메소드는 기본적으로 하나의 데이터를 리턴함

- 두 개 이상의 데이터를 포함하는 데이터클래스를 설계하고 인스턴스를 생성하면 가능함

- 하지만 매번 불필요한 클래스를 만드는 것은 비효율적

- 코틀린은 데이터를 2,3개씩 리턴할 수 있는 클래스를 제공함

- Pair 활용하여 2개 값 리턴 가능

	var chicken = Chicken()
    var eggs = chicken.getEggs()
    var listEggs = eggs.toList()
    
//    first, second로 관리
//    var firstEgg = eggs.first
//    var secondEgg = eggs.second
    
    // 리스트로 관리
    var firstEgg = listEggs[0]
    var secondEgg = listEggs[1]

    println("달걀의 종류는 ${eggs} 입니다.")
    println("리스트 달걀의 종류는 ${listEggs} 입니다.")
    println("첫번째 달걀의 종류는 ${firstEgg} 입니다.")
    println("두번째 달걀의 종류는 ${secondEgg} 입니다.")
}

class Chicken {
    fun getEggs(): Pair<String, String> {
        var eggs = Pair("달걀", "맥반석")
        return eggs
    }
}

 

- Triple 활용하여 3개 값 리턴 가능

fun main() {
    var chicken = Chicken()
    var eggs = chicken.getThreeEggs()
    var listEggs = eggs.toList()
    
//    first, second, third로 관리
//    var firstEgg = eggs.first
//    var secondEgg = eggs.second
//    var eggTime = eggs.third
    
    // 리스트로 관리
    var firstEgg = listEggs[0]
    var secondEgg = listEggs[1]
    var eggTime = listEggs[2]

    println("달걀의 정보는 ${eggs} 입니다.")
    println("리스트 달걀의 정보는 ${listEggs} 입니다.")
    println("첫번째 달걀의 종류는 ${firstEgg} 입니다.")
    println("두번째 달걀의 종류는 ${secondEgg} 입니다.")
    println("달걀은 ${eggTime}에 나왔습니다.")
}

class Chicken {
    fun getTwoEggs(): Pair<String, String> {
        var eggs = Pair("달걀", "맥반석")
        return eggs
    }

    fun getThreeEggs(): Triple<String, String, Int> {
        var eggs = Triple("달걀", "맥반석", 20230101)
        return eggs
    }
}

 

# 자기 자신의 객체를 전달해 효율적으로 처리하기

- 코틀린에서는 Scope functions를 제공함(스코프 함수)

- 객체 사용 시 임시로 scope를 만들어서 편리한 코드 작성 보조

 

1) let function: 중괄호 블록 안에 it으로 자신의 객체를 전달하고 수행된 결과를 반환  

	var strNum = "10"

    var result = strNum?.let {
        // 중괄호 안에서는 it으로 활용함
        Integer.parseInt(it)
        // strNum(문자열 형태)를 진짜 숫자로 변화하는 작업을 it에다가 수행
    }

    println(result!!+1)

 

2) with function: 중괄호 블록 안에 this로 자신의 객체를 전달하고 수행된 결과를 반환

    ※ this는 생략해서 사용할 수 있으므로, null값이 아닐 때만 사용하는 것을 권장

	var alphabets = "abcd"
    // alphabets가 null값이 아님

    with(alphabets) {
//      var result = this.subSequence(0,2)
		// this 생략 가능
        var result = subSequence(0,2)
        println(result)
    }

 

3) also function: 중괄호 블록 안에 it으로 자신의 객체를 전달하고 객체를 반환 

fun main() {
    var student = Student("참새", 10)

    var result = student?.also {
    	// student객체의 age가 50으로 새롭게 바뀐 값이 result가 됨
        it.age = 50
    }
    result?.displayInfo()
    student.displayInfo()
}

class Student(name: String, age: Int) {
    var name: String
    var age: Int

    init {
        this.name = name
        this.age = age
    }

    fun displayInfo() {
        println("이름은 ${name} 입니다")
        println("나이는 ${age} 입니다")
    }
}

 

4) apply function: 중괄호 블록 안에 this로 자신의 객체를 전달하고 객체를 반환

    ※ 주로 객체의 상태를 변화시키고 바로 저장하고 싶을 때 사용

fun main() {
    var student = Student("참새", 10)

    var result = student?.apply {
    // student의 age값을 50으로 apply, result값과 student값에 동시 적용
        student.age = 50
    }
    result?.displayInfo()
    student.displayInfo()
}

class Student(name: String, age: Int) {
    var name: String
    var age: Int
    
    init {
        this.name = name
        this.age = age
    }
    
    fun displayInfo() {
        println("이름은 ${name} 입니다")
        println("나이는 ${age} 입니다")
    }
}

 

5) run function

 (1) 객체에서 호출하지 않는 경우

		var totalPrice = run {
        // 임시로 run 안에 영역을 만들고 그 안에 계산을 통해 도출된 값을 totalPrice에 넣어라
        var computer = 10000
        var mouse = 5000

        computer+mouse
    }
    println("총 가격은 ${totalPrice}입니다")

 

 (2) 객체에서 호출하는 경우

       ※ with와 달리 null 체크를 수행할 수 있어 더 안전하게 사용 가능

fun main() {
    var student = Student("참새", 10)
    // student가 null이 아닐 때에만 호출해라
    student?.run {
        displayInfo()
    }
}

class Student(name: String, age: Int) {
    var name: String
    var age: Int
    
    init {
        this.name = name
        this.age = age
    }
    
    fun displayInfo() {
        println("이름은 ${name} 입니다")
        println("나이는 ${age} 입니다")
    }
}

 

# 스코프 함수의 정리

  scope에서 접근 방식 this scope에서 접근 방식 it
블록 수행 결과를 반환 run, with let
객체 자신을 반환 apply also