3. 함수
자바 메서드와 비슷한 개념으로 어떤 입력을 받아서 자신을 호출한 코드 쪽에 출력값을 반환할 수 있는 재사용 가능한 코드 블록이다.
- 함수 예시
fun main() {
print("반지름을 입력하세요: ")
val radius = readln().toDouble()
print("원의 넓이는 ${circleArea(radius)}")
}
fun circleArea(radius: Double): Double {
return Math.PI * radius * radius
}
fun 키워드를 이용해서 정의한다.
()안에는 파라미터 목록이 들어있고 함수를 호출할 때 넘길 수 있는 데이터를 컴파일러에게 알려준다.
반환 타입은 파라미터 목록() 뒤에 : 후 선언된다.
자바의 경우 메서드 파라미터는 디폴트가 가변이지만 코틀린은 무조건 불변이다.
함수 본문에서 파라미터 값을 변경할 수 없고 컴파일 에러가 발생한다.
타입지정을 생략해도 되는 변수와 달리 파라미터는 항상 타입을 지정해야 한다.
반환 타입도 명시해야 한다. 하지만 경우에 따라서 반환 타입을 생략할 수 있다.
1. 유닛 타입을 반환하는 경우 : 유닛은 자바의 void에 해당하는 코틀린 타입으로 함수가 의미있는 반환값을 돌려주지 않는다는 뜻이다. 이런 함수가 반환하는 값은 Unit이라는 내장 타입에 속하는 Unit이라는 상수다.
2. 식이 본문인 함수 : 어떤 함수가 단일 식으로만 구현될 수 있다면 반환 타입과 중괄호가 생략가능하다. 그러나 일반적으로 블록 구문을 사용해 가독성을 높여주는게 좋으므로 조심스럽게 사용해야 한다.
fun circleArea(radius: Double) = Math.PI * radius * radius
이름이 붙은 인자 방식
자바는 위치 기반 인자를 널리 쓰고 있다. 코틀린은 위치 기반 인자도 사용 가능하지만 이름 붙은 인자 방식도 제공한다.
이름 붙은 인자는 위치가 아닌 파라미터 이름을 명시하여 인자를 전달하는 방식이다. 그렇다면 실제 순서는 중요하지 않다.
fun main() {
print("반지름을 입력하세요: ")
val r = readln().toDouble()
print("원의 색을 입력하세요: ")
val c = readln().toString()
print(makeCircleAreaInfoString(color = c, radius = r))
}
fun makeCircleAreaInfoString(radius: Double, color:String): String {
return "원의 넓이는 ${Math.PI * radius * radius} 이고 색은 $color 입니다"
}
반지름을 입력하세요: 45
원의 색을 입력하세요: Red
원의 넓이는 6361.725123519332 이고 색은 Red 입니다
함수의 영역과 가시성
함수는 정의된 위치에 따라 3가지로 구분된다.
1. 파일에 직접 선언된 최상위 함수
- 디폴트로 public 이고 프로젝트 어디에서나 쓰일 수 있다.
- 경우에 따라 함수가 쓰일 수 있는 위치를 제한하고 싶다면 최상위 함수 정의 앞에 private, internal 키워드를 붙일 수 있다.
private로 비공개 정의를 하면 다른 파일에서는 함수를 쓸 수 없고 정의된 파일 안에서만 사용 가능하다.
internal로 적용하면 함수가 적용된 모듈 내부에서만 사용 가능하다.
2. 어떤 타입 내부에 선언된 멤버 함수
3. 다른 함수 안에 선언된 지역 함수
- 자신을 둘러싼 함수, 블록에 선언된 변수나 함수에 접근할 수 있다. 가시성 변경자(ex: private, internal)를 붙일 수 없다.
패키지와 임포트
자바와 같이 맨 앞에 패키지 이름을 지정하면 파일에 있는 모든 최상위 선언을 지정한 패키지 내부에 넣을 수 있다.
패키지를 지정하지 않으면 컴파일러는 파일이 디폴트 최상위 패키지에 속한다고 가정한다. (디폴트 최상위 패키지는 이름이 없음)
조건문
- if 문
자바와 비슷한 문법이다.
다른 점은 조건은 항상 boolean 타입의 식이여야 하고 식으로 사용할 수 있다는 것이다.
단 코틀린은 자바와 달리 3항 연산자가 없다. 이를 상쇄해준다.
fun max(a: Int, b: Int): Int = if (a > b) a else b
순서가 정해진 값 사이의 수열을 표현하는 몇 가지 타입을 제공한다. for 루프로 어떤 수 범위를 반복해야 할 때는 이런 타입이 유용하다.
이런걸 범위라고 부른다.
val chars = 'a'..'h'
val twoDigits = 10..99
val zero2One = 0.0..1.0
범위는 시작 값과 끝 값을 포함한다.
끝 값이 제외된 범위를 만드는 다른 연산도 있다. 이건 정수 타입만 가능하다.
val num = 10 until 100 // 10..99와 같다. 100은 포함하지 않는다.
역방향 범위를 생성하는 표현도 있다.
val num = 10 downTo 1 // 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
연관 개념으로 진행이 있다. 정해진 간격만큼 떨어져 있는 범위를 만들 수 있다.
1..10 step 3 // 1, 4, 7, 10
10 downTo 1 step 3 // 10, 7, 4, 1
in 연산을 사용하면 어떤 값이 범위 안에 들어있는지 알 수 있다. 반대 연산인 !in도 있다.
val num = readln().toInt()
println(num in 10..99)
// 출력 부분
78
true
1
false
- when
자바에서 switch 문과 비슷하나 차이점이 몇가지 있다.
switch는 정수형, 문자, 문자열 등 한정된 타입만 가능하지만 when은 모든 타입을 사용할 수 있다.
식으로 만들 수 있으며 이럴땐 else를 꼭 포함해야 한다.
// when 사용 예제
when (readln().toInt()) {
in 0..10 -> println("x belongs to the range 0..10")
in 11..20 -> println("x belongs to the range 11..20")
else -> {
println("x doesn't belong to the range 0..20")
}
}
루프문
- while / do-while : 자바와 매우 유사하다.
- for 루프와 이터러블
val numArray = arrayOf(1, 2, 3, 4, 5)
//for 사용 예제
for (i in numArray) {
println(i)
}
자바보다 좀 더 간소화 된 문법으로 사용할 수 있다.
루프 변수에는 val이나 var를 붙이지 않고 자동으로 불변 값이 된다.
루프 제어 흐름 변경하기
break : 즉시 루프를 종료, 루프 바로 다음 문으로 이동한다.
continue : 현재 루프 이터레이션을 마치고 조건 검사로 바로 진행한다.
예외처리
코틀린은 클래스 인스턴스를 생성할 때 new 를 붙이지 않듯이 예외를 던질때도 new를 사용하지 않는다.
// when 사용 예제
when (readln().toInt()) {
in 0..10 -> println("x belongs to the range 0..10")
in 11..20 -> println("x belongs to the range 11..20")
else -> {
// 예외 던지기
throw IllegalArgumentException("x is out of range")
}
}
자바와 똑같이 try-catch 문을 사용해서 예외 처리를 할 수 있다. 다만 자바처럼 catch(Exception1 | Exception2)와 같은 구문을 사용해 처리 할 수는 없고 catch문을 여러개 사용해서 처리해야 한다.
'개발 > Java & Kotlin' 카테고리의 다른 글
내가 보려고 쓰는 Java와 Kotlin 차이 정리 #3 (0) | 2024.10.25 |
---|---|
내가 보려고 쓰는 Java와 Kotlin 차이 정리 #1 (0) | 2024.10.10 |
JAVA에서 volatile란 무엇인가!? (0) | 2021.03.31 |
OPEN JDK 1.8 윈도우 설치 방법 (0) | 2020.06.16 |
web.xml에 welcome-file 설정하는 방법 (0) | 2019.04.08 |