Recent Posts
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- taint
- mp4fpsmod
- 개성국밥
- vfr video
- 달인막창
- kotlin
- 겨울 부산
- 코루틴 컨텍스트
- Value too long for column
- PytestPluginManager
- k8s #kubernetes #쿠버네티스
- 오블완
- preemption #
- Spring Batch
- terminal
- 헥사고날아키텍처 #육각형아키텍처 #유스케이스
- JanusWebRTCServer
- 자원부족
- 코루틴 빌더
- 티스토리챌린지
- table not found
- VARCHAR (1)
- python
- 깡돼후
- JanusWebRTC
- PersistenceContext
- pytest
- tolerated
- JanusWebRTCGateway
- JanusGateway
Archives
너와 나의 스토리
[Kotlin] 코틀린 기초2 - 스마트 캐스트, 이터레이션(for 문, 컬렉션이나 원소 검사), 예외 처리 본문
Programming Language/Kotlin
[Kotlin] 코틀린 기초2 - 스마트 캐스트, 이터레이션(for 문, 컬렉션이나 원소 검사), 예외 처리
노는게제일좋아! 2021. 6. 11. 00:09반응형
스마트 캐스트
interface Expr
class Num(val value: Int) : Expr // Expr 인터페이스를 구현한다
class Sum(val left: Expr, val right: Expr) : Expr
- 위의 예제를 보자.
- Expr 타입의 객체라면 어떤 것이나 Sum 연산의 인자가 될 수 있다. 즉, Num이나 다른 Sum이 인자로 올 수 있다.
- (1+2)+4를 계산한다고 하자.
fun eval(e: Expr): Int {
if(e is Num){
val n = e as Num
return n.value
}
if(e is Sum){
return eval(e.right)+eval(e.left)
}
throw IllegalArgumentException("Unknown expression")
}
fun main(args: Array<String>) {
println(eval(Sum(Sum(Num(1), Num(2)),Num(4)))) // output: 7
}
- 변수 타입을 검사하기 위해 is 명령어를 사용한다. -> 자바에서의 instanceof와 비슷
- 일단 is 명령어로 검사하고 나면 마치 처음부터 그 변수가 원하는 타입으로 선언된 것처럼 사용할 수 있다.
- if문을 보면 (e is Num)부분을 거친 후에 변수 e를 따로 Num으로 캐스팅하지 않아도 자연스럽게 Num으로 인식하고 있다.
- 이렇게 컴파일러가 자동으로 캐스팅을 수행해주는 것을 스마트 캐스트(smart cast)라고 부른다.
- 스마트 캐스트는 is로 변수에 든 값의 타입을 검사한 다음에 그 값이 바뀔 수 없는 경우에만 작동한다.
- 즉, 스마트 캐스트를 사용하려면 그 프로퍼티는 반드시 val이어야 하며 커스텀 접근자를 사용한 것이어도 안 된다.
- 커스텀 접근자를 사용하는 경우에는 val이 아니거나 val이지만 해당 프로퍼티에 대한 접근이 항상 같은 값을 리턴한다고 확신할 수 없기 때문이다.
- 즉, 스마트 캐스트를 사용하려면 그 프로퍼티는 반드시 val이어야 하며 커스텀 접근자를 사용한 것이어도 안 된다.
- 원하는 타입으로 명시적으로 타입 캐스팅하려면 as 키워드를 사용할 수 있다.
-
val n = e as Num
- 객체가 타입 변환이 가능한 올바른 타입이 아니라면 ClassCastException이 발생한다.
- 이런 경우를 예방하기 위해 as? 연산자를 사용할 수 있다.
-
val n = e as? Num
- e를 Num 타입으로 변경할 수 없다면 null이 반환된다.
-
if와 when
- 코틀린의 [ if ( a>b) a else b ]는 자바의 a>b ? a:b처럼 작동한다.
- 즉, 코틀린은 if가 값을 만들어 내기 때문에 자바와 달리 3항 연산자가 따로 없다.
- 이런 특성을 이용해 위해서 작성한 eval() 메서드를 리팩토링할 수 있다.
fun eval(e: Expr): Int {
when (e) {
is Num ->
e.value
is Sum ->
eval(e.right) + eval(e.left)
else ->
throw IllegalArgumentException("Unknown expression")
}
}
- is Num -> { ... } 형식으로 분기를 블록으로 만들 수 있다.
이터레이션: while 문과 for문
while 문
- while문과 do-while 문이 있으며 이 두 루프의 문법은 자바와 동일하다. 작성 방식도 동일
for 문
- 코틀린에서는 범위(range)를 사용해 for 문을 돌린다.
- '..' 연산자로 시작 값과 끝 값을 연결해 범위를 표현한다.
- a..b => [a, b]
- 예: for ( i in 1..100 )
- 1부터 100까지의 정수에 대해 이터레이션(끝 값도 포함)
- 'A'..'F' => A, B, C, ..., F
- a..b => [a, b]
- until
- a until b => [a, b)
- 예: for ( i in 1 until 5)
- 위 예제에서 i는 1, 2, 3, 4가 된다.
- 증가 값을 가지고 범위 이터레이션할 수 있다.
- 예: for( i in 100 downTo 1 step 2)
- '100 downTo 1': 100에서 시작해서 1까지 내려가라는 소리
- 'step 2'는 2씩 값이 내려간다는 소리이다.
- 위 예제에서 i는 100, 98, ..., 2가 된다.
- 맵에 대한 이터레이션
val list = arrayListOf(10,11,12)
for((index, element) in list.withIndex()){
println("$index: $element")
}
/*
output:
0: 10
1: 11
2: 12
*/
in으로 컬렉션이나 범위의 원소 검사
fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'
fun isNotDigit(c: Char) = c !in '0'..'9'
- when 식에서도 사용 가능하다.
fun recognize(c: Char) = when(c) {
in '0'..'9' -> "It's a digit!"
in 'a'..'z', in 'A'..'Z' -> "It's a letter!"
else -> "I don't know"
}
코틀린의 예외 처리
예외 던지는 방법
- 예외를 던지는 방법은 자바와 비슷하다.
fun isValid(percentage: Int) {
if (percentage !in 0..100) {
throw IllegalArgumentException(
"A percentage value must be between 0 and 100: $percentage"
)
}
}
try, catch, finally
- 자바와 마찬가지로 try, catch, finally 절로 예외를 처리한다.
- 다음은 파일에서 각 줄을 읽어 수로 변환하되 그 줄이 올바른 수 형태가 아니면 null을 반환하는 예제이다.
fun readNumber(reader: BufferedReader): Int? {
try {
val line = reader.readLine()
return Integer.parseInt(line)
} catch (e: NumberFormatException) {
return null
} finally {
reader.close()
}
}
- 자바와 throws 절이 없다.
- 자바에서는 함수를 작성할 때 함수 선언 뒤에 throws IOException을 붙여줘야 한다.
- 이는 IOException이 checked exception이고, 자바에서는 checked exception을 명시적으로 처리해야 하기 때문이다.
- 코틀린은 checked exception과 unchecked exception을 구별하지 않는다.
- 코틀린에서는 함수가 던지는 예외를 지정하지 않고, 발생한 예외를 잡아내도 되고 잡아내지 않아도 된다.
- try를 식으로 사용할 수 있다.
- 코틀린의 try 키워드는 if나 when과 마찬가지로 식이다.
- 따라서 try의 값을 변수에 대입할 수 있다.
fun readNumber(reader: BufferedReader) {
val number = try {
Integer.parseInt(reader.readLine())
} catch (e: NumberFormatException) {
throw NumberFormatException()
}
println(number)
}
fun main(args: Array<String>) {
val reader1 = BufferedReader(StringReader("785"))
readNumber(reader1)
// output: 785
val reader2 = BufferedReader(StringReader("not a number"))
readNumber(reader2)
// output: Exception in thread "main" java.lang.NumberFormatException
}
출처:
- [Kotlin IN ACTION]
- [코틀린을 다루는 기술]
반응형
'Programming Language > Kotlin' 카테고리의 다른 글
[Kotlin] 클래스와 인터페이스2 - 데이터 클래스/클래스 위임/object 키워드 사용 (0) | 2021.06.15 |
---|---|
[Kotlin] 클래스와 인터페이스1 - 초기화(주 생성자와 부 생성자)/가시성 변경자/프로퍼티 (0) | 2021.06.14 |
[Kotlin] 함수 정의와 호출1 - 컬렉션/확장 함수/로컬 함수/문자열을 정규식으로 나누기 (0) | 2021.06.12 |
[Kotlin] 코틀린 기초1 - 함수, 변수, 클래스, property, enum, when (1) | 2021.06.10 |
[Kotlin] Spring Boot로 RESTful 웹 서비스 만들기 (4) | 2021.06.09 |
Comments