본문 바로가기

Kotlin

[Kotlin] 2. 코틀린 기본 - 함수(2)

#가변 인자 함수

  • 인자의 개수가 달라질 수 있는 함수
  • 컴파일러가 가변 인자들을 배열로 만들어 줌
  • vararg 변경자를 이용
  • 이미 만들어져 있는 배열을 가변 인자로 사용 가능 = *(스프레드 연산자)를 사용
class Student(var name: String, var age: Int) {
    //가변 인자 함수
    fun printFriend(vararg friends :String) {          
        println("Tina's Friends = ${friends.asList()}")  //전달받은 배열 friends를 print
    }
}

fun print() {
        val student = Student("Tina", 19);
    	
        //1) 가변 인자 함수 호출
        student.printFriend("Scott", "Dean", "Bobby") // Tina's Friends = [Scott, Dean, Bobby]
    	
        //2) 가변 인자 함수 호출 - *(스프레드 연산자)를 통해 명시적으로 배열을 넘김
        val array = arrayOf("Dean", "Bobby") //-> arrayOf도 가변 인자 함수
        student.printFriend("Scott",*array, "Bieber" ) // Tina's Friends = [Scott, Dean, Bobby, Bieber]
}

 

#중위 호출(Infix Call)

*수식을 쓸 때 피연산자 사이 중간에 연산자(덧셈, 뺄셈) 이 있는 식을 중위 표기 Infix라고 한다

  • 중위 표기 연산 식 처럼, 수신 객체메소드 인자 사이에 메소드 이름을 넣어서 사용하는 방식
  • 메소드의 인자가 하나뿐이야 함.. 당연쓰
  • 중위 호출로 호출되게 하려면 infix 변경자를 선언 
  • 아래 Student 예제에서 수신객체 = student , 인자 = "Scott"
  • 장점 : 코틀린 함수 호출의 가독성을 향상
class Student(var name: String, var age: Int) {
    //중위 함수
    infix fun partner(partnerNm: String) = println("${this.name}'s partner = $partnerNm")
}

fun print() {
    val student = Student("Tina", 19);

    //'partner' 메소드를 일반적인 방식으로 호출함
    student.partner("Scott") 	//Tina's partner = Scott
    //'partner' 메소드를 중위 호출 방식으로 호출함
    student partner "Scott" 	//Tina's partner = Scott
}

또 다른 예제로는

val pair = "Tina" to "Scott"  //중위 호출 방식으로 to 를 호출 -> Pair를 반환

 

#구조 분해 선언(destructuring declaration)

  • 객체의 값들을 분해해서 한번에 다수의 변수에 초기화 하는 기능

[예시1]

        val students = listOf("Tina", "Scott", "Dean")
        // 루프에서의 구조 분해 선언
        for ((index, partner) in students.withIndex()) {
            println("student $index =$partner")
        }

 

[예시2]

        //Pair 인스턴스에서의 구조 분해 선언
        val (student, partner) = "Tina" to "Scott"
        println("student = $student") //student = Tina
        println("partner = $partner") //partner = Scott

 

 

#로컬 함수(Local Function)

  • 함수 안에 함수를 만들어서 사용하는 방법
  • 장점 : 어떤 함수 안에 중복되는 코드를 로컬 함수로 정의 해 중복을 피할 수 있다 -> 코드 깔끔

[일반적인 함수] 

//Student 클래스 선언
class Student(val studentNum: Int, val name: String, val nickName: String)

//Student 객체를 저장 하기 전 validate 체크 하는 함수라 가정
fun saveStudent(student: Student) {
    if (student.name.isEmpty()) {
        throw IllegalArgumentException("Number ${student.studentNum} Student Name is Empty")
    }
    if (student.nickName.isEmpty()) {
        throw IllegalArgumentException("Number ${student.studentNum} Student NickName is Empty")
    }

    // ....
}

 

[로컬함수로 변환] : 로컬 함수 안에서 바깥 함수의 파라미터/변수 모두 사용 가능

fun saveStudent(student: Student, field : String) {
    //로컬 함수 생성
    fun validateStr(targetStr: String) {
        if (targetStr.isEmpty()) {
            throw IllegalArgumentException("Number ${student.studentNum} Student $field is Empty")
        }
    }
    validateStr(student.name, "Name")
    validateStr(student.nickName, "NickName")

    // ....
}

중복되는 Empty Validation 코드를 로컬 함수로 변환 해서 중복을 방지했다

 

validateStr 함수를 일반 함수로 생성 할 수도 있지만

자잘한 메소드가 많아지면 메소드간 관계 파악이나 소스 파악이 힘들어지는 경우가 발생

 

validateStr 함수를 saveStudent 함수에서만 사용된다면 로컬 함수로 사용함으로써 명확하게 코드 작성이 가능하다

 

출처 : Kotlin In Action - 에이콘 출판사

(위 도서를 학습하고 개인 학습용으로 정리한 내용입니다)


문제 있을시 알려 주세요.

 

좋은 하루 되세요!