TIL_006 | Kotlin, 익숙한 듯 익숙하지 않은 친구

묘한묘랑·2023년 12월 4일
0

TIL

목록 보기
6/31

Kotlin으로 Programmers의 알고리즘을 풀다 생긴 일이다.

문제

삼항연산자.

이번에 kotlin을 사용하며 문제를 푸는 도중 삼항연산자를 사용하려 하니 곧바로 세상에서 제일 보기 싫은 빨간줄이 생기기에 도대체 왜? 라는 생각이 들어 곧바로 kotlin 삼항연산자 라고 구글링을 하자 kotlin에서는 삼항연산자를 지원하지 않는다는 글이 바로 보였다.

사실 예전에는 삼항연산자를 오히려 잘 안쓰는 편이었는데 if문이 많아지는 것이 점점 보기 안좋아 삼항연산자를 자주 쓰는 편이었다.

글을 더 읽어보니 삼항연산자 처럼... 처...럼... 한줄로 if문을 작성하라고 한다.

까라면 까야지

when

when 문법은 생각보다 java 17버전의 switch 문법을 닮아 생각보다 반가웠다.

// Kotlin의 when문법
when(value){
	1 -> println("a")
    2 -> println("b")
}
// java17의 switch 문법
switch (value) {
    case 1 -> System.out.println("1");
    case 2 -> System.out.println("2");
}

Lambda

List를 사용할 때 forEach Method를 사용하려 했는데 Lambda로 사용하는 방식이 있기에 채택해보기로 했다.

fun solution(s: String): String{
    var result = ArrayList<String>();
    val splited = s.split(" ");
    splited.forEach{
        var str = "";
        it.forEachIndexed { index, c ->
            if(index == 0) {
            str += c.uppercaseChar();
            return; // 에러지점.
            }
            str += if(index % 2 == 0) c.uppercaseChar(); else c.lowercaseChar();
        }
        result.add(str);
    }
    return result.joinToString(" ");
}

여기서 부터 급격하게 이상함을 느꼈다.
내부에서 return을 하는데 return type을 String으로 원한다기에 뭔가 이상했다.
그래서 그냥 아무 문자열을 return하기로 하였고 그리고 결과를 출력하는 순간.
아, 이상하다. 많이 이상하다.
그 아무 문자열이 결과로 출력되는 것이 아닌가.

그래서 일단 return문을 없애고 if문도 없애고 생각없이 실행하였는데. 어라...? 0을 나머지 | 나누기 연산을 해도 에러가 나지 않았다.

class Solution {
    fun solution(s: String): String{
    var result = ArrayList<String>();
    val splited = s.split(" ");
    splited.forEach{
        var str = "";
        it.forEachIndexed { index, c ->
            str += if(index % 2 == 0) c.uppercaseChar(); else c.lowercaseChar();
        }
        result.add(str);
    }
    return result.joinToString(" ");
}
}

일단은 위와 같이 완성했다.

완성한 이후 아무리 생각해봐도 함수를 정의해서 그 정의된 함수를 호출 하는 것인데 그 함수가 caller 함수를 종료 시킨다는 것이 이해가 가지 않았다. 아니 심지어 forEach문 내부에 있었기에 더욱더 이해가 가지 않았다. caller의 caller를 종료 시킨다는 것이 너무 이해가 가지 않았기에 계속해서 검색해 보았다.

KeyWord -> inline, label

kotlin lambda로 검색해보았을 때 가장 많이 보는 것이 inline이라는 KeyWord였다. 그래서 inline함수에 관하여 검색을 하니 모든 의문이 풀렸다.
inline의 함수의 경우 java code로 변환 할 때, byte코드를 그대로 복사 붙여넣기 하듯이 변환 된다고 한다.

// ArrayList<String>.forEach의 원형
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}

또한

{ a -> (함수 내용) } 의 형태로 람다 값을 줄 경우 inline으로 선언된 것과 같은 효과를 보는 것 같다.

그리고 label에 관해서인데, lambda 내부에서 return을 할 경우 label을 줌으로써 lambda부분에서만 return을 할 수 있는 방법이 있지만 개인적으로 c언어의 goto문이 떠올라 그 방법을 써야만 하는 상황이 아니라면 차라리 익명함수를 사용하는 형식으로 할 것 같다.

또한 noinline keyword를 통하여 inline이 아닌 함수 호출 형식으로 변환이 가능하다.

profile
상황에 맞는 기술을 떠올리고 사용할 수 있는 개발자가 되고 싶은 개발자

0개의 댓글