본문 바로가기
발전로그/책장로그-개발

kotlin in action 03 (3.5~3.7)

by 4lleycat 2022. 3. 1.

3.5 문자열과 정규식 다루기

  • 코틀린의 문자열은 자바의 문자열과 같다
    • 코틀린 코드의 문자열을 자바 메서드에, 자바 문자열을 코틀린 표준 라이브러리 메서드에 넘겨도 호환

3.5.1 문자열 나누기

  • split 메서드
    • 자바에서는 String.split(".") 문자열을 메서드에 받음
    • 코틀린에서는 정규식(Regex) 값을 받음
    • 자바와 달리 코틀린은 확장 함수로 여러 개의 문자열을 받을 수 있다.
fun main() {
    println("12.345-6.A".split("\\.|-".toRegex()))
    println("12.345-6.A".split(".","-")) //delimeters multiple
}
>>>>>>>>>>>
[12, 345, 6, A]
[12, 345, 6, A]

3.5.2 정규식과 3중 따옴표(triple quotes)로 묶은 문자열 (python smell~)

fun main() {
    parsePath("Users/yole/kotlin-book/chapter.doc")
}

fun parsePath(path:String) {
    val regex = """(.+)/(.+)\.(.+)""".toRegex()
    val matchResult = regex.matchEntire(path)
    if (matchResult != null) {
        val (directory, filename, extension) = matchResult.destructured //구조분해 통해 각 변수적용
        println("dir: $directory, name: $filename, ext: $extension")
    }
}
>>>>>>>>>>
dir: Users/yole/kotlin-book, name: chapter, ext: doc
  • 3중 따옴표에서는 어떤 문자도 이스케이프 할 필요가 없다

3.5.3 여러 줄 3중 따옴표 문자열

  • 3중 따옴표 문자열은 이스케이프를 피하기 위한 용도 만은 아니다
  • 줄 바꿈이 있는 텍스트를 쉽게 문자열로 바꿔줌
fun main() {
    // 줄바꿈 뿐아니라 들여쓰기까지 표현
    println("""Users/
        |yole/
        |kotlin-book/
        |chapter.doc""")
}

>>>>>>>>>>>>>>>
Users/
        |yole/
        |kotlin-book/
        |chapter.doc
  • 기존 라이브러리를 새 언어에서 활용하는 패턴을 라이브러리 알선(pimp my library) 패턴이라 부른다

3.6 코드 다음기: 로컬 함수와 확장

class User(val id: Int, val name: String, val address: String)

fun main() {
    saveUser(User(1, "", ""))
    saveUserLocalFun(User(1, "", ""))
    saveUserLocalFunParam(User(1, "", ""))
    val user = User(1, "", "")
    user.validateSave()
}

//코드 중복 예시
//user DB 저장
fun saveUser(user: User) {
    if (user.name.isEmpty()) {
        throw IllegalArgumentException("can't save user ${user.id}: empty name")
    }

    if (user.address.isEmpty()) {
        throw IllegalArgumentException("can't save user ${user.id}: empty address")
    }
}


//로컬함수를 이용 코드중복 줄이기
fun saveUserLocalFun(user:User) {
    fun validate(user: User, value: String, fieldName: String) {
        if (value.isEmpty()) {
            throw IllegalArgumentException("can't save user ${user.id}: empty $fieldName")
        }
    }
    validate(user, user.name, "name")
}

// 로컬 함수에서 바깥함수의 파라미터 접근하기
fun saveUserLocalFunParam (user: User) {
    fun validate(value: String, fieldName: String) { // user 파리미터 중복 사용 안함
        if (value.isEmpty()) {
        	//외부 user 파라미터 직접 접근가능
            throw IllegalArgumentException("can't save user ${user.id}: empty $fieldName}")
        }
    }
    validate(user.name, "name")
}

// 확장 함수로 추출
fun User.validateSave() {
    fun validate(value: String, fieldName: String) {
        if (value.isEmpty()) {
            throw IllegalArgumentException("can't save user $id: empty $fieldName") // User의 프로퍼티 직접 사용가능
        }
    }
    validate(name, "name")
}

>>>>>>>>>>>>>
Exception in thread "main" java.lang.IllegalArgumentException: can't save user 1: empty name
.........

 

  • 중첩 함수의 깊이가 깊어지면 코드 읽기가 힘들어진다, 단 한 단계만 함수를 중첩할 것

3.7 3장 요약

  • 코틀린은 자체 컬렉션 클래스를 정의하지 않지만 자바 클래스를 확장해서 더 많은 Api를 제공한다
  • 함수 파라미터의 디폴트 값을 정의하면 오버 로딩한 함수를 정의할 필요성이 줄어든다
  • 이름 붙인 인자(시그니처)를 사용하면 가독성을 높일 수 있다
  • 코틀린은 최상위 함수, 프로퍼티를 직접 선언할 수 있다. (꼭 클래스의 멤버가 아니어도 됨)
  • 확장 함수와 프로퍼티를 사용하면 모든 클래스의 소스코드 변경 없이 확장이 가능하다
  • 중위 호출을 통해 인자가 하나밖에 없는 메서드나 확장 함수를 더 깔끔한 구문으로 호출할 수 있다
  • 3중 따옴표 문자열 지원
  • 로컬 함수로 중복을 제거할 수 있다