본문 바로가기

Kotlin

🚥코틀린의 흐름제어&예외처리

www.notion.so/3a1eca95641e441aba34b3434f5a434d

 

코틀린의 흐름제어&예외처리

2.5 흐름 제어 ⭐⭐⭐⭐

www.notion.so

 

2.5 흐름 제어 ⭐⭐⭐⭐


조건문

if-else 문

Java

Kotlin 값을 만들어 내는 식!

if(a>b) a else b //  =java의 3항 연산자 a>b ? a:b

when 문

코틀린에서 when은 자바의 switch보다 강력하다.

Java 분기 조건에 상수(enum 상수나 숫자literal)만 사용 가능

Kotlin 분기 조건으로 객체 허용

  1. when으로 enum 클래스 다루기
    fun getMnemonic(color: Color){
    	when(color){
    		Color.RED->"Richard"
    		Color.ORANGE->"Of"
    		Color.YELLOW -> "York"
    		Color.GREEN->"Gave"
    		Color.BLUE->"Battle"
    		Color.INDIGO -> "In"
    		Color.VIOLET->"Vain"
    	}
    }
    >>>println(getMnemonic(Color.RED))
    Richard
  1. when 과 임의의 객체를 함께 사용
    fun mix(c1:Color,c2:Color){
    	when(setOf(c1,c2)){ // when식의 인자로 아무 객체나 사용할 수 있다. 
    		setOf(RED,YELLOW) -> ORANGE
    		setOf(YELLOW,BLUE) -> GREEN
    		setOf(BLUE,VIOLET) -> INDIGO
    		else->throw Exception("Dirty Color") //배치되는 분기 조건이 없으면 실행
    }

    Set setOf 여러객체를 그 객체들을 포함하는 집합인 Set 객체로 만드는 setOf 함수가 있다.

    when의 분기 조건 부분에 식을 넣을 수 있기 때문에 많은 경우 코드를 더 간결하고 아름답게 작성할 수 있다.

    단점

    함수가 호출될 때마다 set 인스턴스를 생성한다. 보통은 이런 비효율성이 크게 문제가 되지 않지맘ㄴ 이 함수가 자주 호출된다면 불필효한 가비지 객체가 늘어난다.

  1. 인자없는 when 사용

    fun mix(c1:Color,c2:Color){
    	when{ // when에 아무런 인자도 없다. 
    		(c1==RED&&c2==YELLOW)||	(c1==YELLOW&&c2==RED) -> ORANGE
    		(c1==YELLOW&&c2==BLUE)||(c1==BLUE&&c2==YELLOW) -> GREEN
    		(c1==BLUE&&c2==VIOLET)||(c1==VIOLET||c2==BLUE) -> INDIGO
    		else->throw Exception("Dirty Color") //배치되는 분기 조건이 없으면 실행
    }

    when에 아무 인자도 없으려면 각 분기의 조건이 불리언 결과를 계산하는 식이어야 한다.

    장점 추가 객체를 만들지 않는다.

    단점 가독성은 더 떨어진다.

  1. 리팩토링 if를 when으로 변경

대상을 iteration: 반복문

while 문

while과 do- while Java와 똑같다.

while(조건){  //조건이 참인 동안 본문 실행
	본문
}
===============================
do{
	본문
}while(조건) //맨 처음에 무조건 본문을 한 번 실행한 다음, 조건이 참인 동안 반복 실행

for 문

Java for-each 루프만 존재

Kotlin for <아이템> in <원소들> - c#과 유사. + map iteration (컬렉션 응용가능)

//map iteration
val binaryREps=TreeMap<Char,String>()//키에 대해 정렬하기 위해 TreeMap을 사용.
for (c in 'A'..'F'){ //A부터F까지 문자의 범위를 사용해 이터레이션.
	val binary=Integer.toBinaryString(c.toInt()) //아스킬 코드를 2진으로 변환.
	binaryReps[c]=binary //c를 키로 c의 2진 표현을 맵에 넣는다
}

for ((letter,binary)in binaryReps ){ 
	//map에 대해 이터레이션. map에 대한 key, value 를 두 변수에 각각 대입
	println("${letter}:${binary}")
}
💡
객체를 풀어서 각 부분을 분리하는 구조 분해 문법 → 코틀린 인 액선 7.4.1장 원소를 풀어서 letter(키)와 binary(2진표현)라는 두 변수에 저장. ⇒ 키를 사용해 맵의 값을 가지고 오거나 키에 해달하는 값을 설정할 수 있음!
//colloection iteration
val list = arrayList("10","11","1001")
for ((index,element)in list.withIndex()){ //인덱스와 함께 컬렉션을 이터레이션.
	println("${index}:${element}")
}

>>> 0:10
		1:11
		2:1001   
💡
객체를 풀어서 각 부분을 분리하는 구조 분해 문법 컬렉션에도 사용가능. 원소의 현재 인덱스를 유지하면서 컬렉션을 이터레이션할 수 있다. ⇒ 인덱스를 저장하기 위한 변수를 별도로 선언하고 루프에서 매번 그 변수를 증가시킬 필요가 없다.

범위 & 수열

Java for문 - 초깃 값, 증가 값, 최종 값을 사용한 루프를 대신하기 위해

Kotlin에서는 범위range를 사용한다.

범위 range

  1. (보통 정수타입의 )두 값으로 이루어진 구간이다.
  1. .. 연산자로 시작 값과 끝 값을 연결한다.
  1. 폐구간(양끝을 포함하는 구간)이다.
val oneToTen = 1..10 //1과 10은 범위에 포함.

수열progression

어떤 범위에 속하 값을 일정한 순서로 이터레이션하는 경우.

for (i in 100 downTo 1 step 2){ 
	println(fizzBuzz(i))
}
//downTo 는 역방향 수열
//step 2 는 증가 값이 절댓값 2로 바뀜.
// + until 도 있는데 이건 끝 값을 포함하지 않는 반만 닫힘 범위.

2.7 예외 ⭐⭐⭐


함수는 정상적으로 종료할 수 있지만, 오류가 발생하면 예외exception던질 throw할 수 있다.

발생한 예외를함수 호출 단에서 처리catch 할 수 있다. 그렇지 않다면 함수 호출 스택에서 거슬러 올라가면서 예외를 처리하는 부분이 나올 떄까지 예외를 다시 던진다rethrow.

throw exception

//throw exception
val percentage=
	if(number in 0..100)
		number
	else throw IllegalArgumentException(
		"A percentage value must be between 0 and 100 :${number}")

//throw도 값을 만들어 내는 식이다.

exception catch

try롸 catch, finally절 사용.

fun readNumber(reader:BufferReader):Int?{
		//함수가 던질 수 있는 예외를 명시할 필요가 있다.
	try{
		val line=reader.readLine()
		return Integer.parseInt(line)
	}
	catch(e:NumberFormatException){
		//예외타입을 :의 오른쪽에 쓴다.
		return null
	}
	finally{
		//자바와 똑같이 작동.
		reader.close()
	}
}

자바와 가장 큰 차이는 throws 절이 코드에 없다는 점!!

자바에서는 함수를 작성할 때 함수 선언 뒤에 throws IOException을 붙여야 한다.