함수생성
간단한 함수
코틀린은 KISS ( Keep It Simple Stupid ) 원칙을 준수한다. 단순하게 작성이 가능하다.
fun greet() = "hello" // 가장 심플한 메소드
정적타입의 변수와 마찬가지로 메소드의 리턴타입 또한 타입 추론이 가능하다. 위 코드를 보면 코틀린은 리턴타입이 String 타입이라는 것을 추론할 수 있다.
fun greet() : String = "hello" // 위 코드와 동일
코틀린은 표현식이 많고 명령문은 적다. 아래의 메소드가 표현식이다.
fun sayHello() = println("hello")
코틀린 메소드에서 return 타입은 필수입니다. 위와 같이 리턴타입이 없는 println을 사용할 경우는 Unit 을 리턴합니다. Unit은 아무런 값도 리턴하지 않는 메소드에서 리턴되는 타입입니다.
복잡한 함수
한 줄로 처리되지 않는 복잡한 함수는 자바와 마찬가지로 블록을 작성하고 블록 내에 로직을 작성합니다.
fun max(numbers: IntArray): Int { var large = Int.MIN_VALUE for ( number in numbers ) { large = if (number > large) number else large } return large }
기본인자와 명시적 인자
Java의 오버로딩과 비슷한 의도로 사용되는 기능입니다.
Java에서 하나의 메소드가 있다고 가정하고 그 메소드를 여러군데에서 사용 중 입니다.
public Integer sum(int a, int b) { // logic.. }
요청사항이 들어와 하나의 파라미터를 추가할 경우 기존의 메소드는 수정하지 않고 메소드명을 동일하게 한 후 파라미터만 추가하여(오버로드) 작성할 수 있습니다.
// 오버로딩 public Integer sum(int a, int b, int c) { // logic.. }
코틀린은 오버로딩은 지원하지 않지만 명시적 인자를 통해서 위와 비슷한 기능을 구현할 수 있습니다.
기본인자
일반적으로 메소드에 기본인자로만 구성된 경우입니다.
fun greet(name: String): String = "Hello $name"
기본 인자 + 명시적 인자
위 메소드에서 새로운 요청사항이 왔고 새로운 파라미터를 추가할 경우 기본 인자와 명시적 인자를 같이 구성하여 메소드를 수정할 수 있습니다.
fun greet(name: String, msg: String = "Hello"): String = "$msg $name"
fun greet(name: String, msg: String = "Hi ${name.length}") = "$msg $name"
println(greet("Scott", "Howdy")) println(greet("Scott"))
명시적 아규먼트 이용방법
코틀린에서는 아규먼트를 명시하여 순서에 상관없이 개발자가 원하는 아규먼트에 값을 대입할 수 있습니다.
// 명시적 아규먼트를 이용하자! fun createPerson(name: String, age: Int, height: Int, weight: Int) { println("$name $age $height $weight") } createPerson("Jake", 12, 152, 43) // IDE 도움이 없다면 파라미터가 의미하는 바를 알 수 없다. createPerson(name = "Jake", age = 12, height = 152, weight = 43) // Good!! createPerson(name = "Jake", 12, weight = 43, height = 152) // Good!!
다중인자와 스프레드
여러 개의 인자
Java에서는 '...' 으로 배열( 여러개의 인자 ) 를 받을 수 있습니다.
public int sum(Integer... params) { // logic.. }
코틀린에서는 이와 비슷한 기능으로 vararg을 사용합니다.
fun varargMax(vararg numbers: Int): Int { var large = Int.MIN_VALUE for (number in numbers) { large = if (number > large) number else large } return large } println(varargMax(1, 5, 2, 5, 12)) // use
위에서 학습한 명시적 인자와도 함께 사용할 수 있습니다.
fun greetMany(msg: String, vararg names: String) { println("$msg ${names.joinToString(", ")}") } greetMany(msg = "Hello", "James", "John", "Tom") // use
스프레드 연산자
vararg 변수를 선언할 경우 배열이나 리스트를 전달할 수 없습니다. 이와 같은 경우에 스프레드 연산자를 사용하여 넘길 수 있습니다.
val values = intArrayOf(1, 52, 11) println(varargMax(*values)) // 스프레드 연산자
구조분해
구조화란 다른 변수의 값으로 객체를 만드는 것이다. 구조분해는 이와 반대로 이미 존재하는 객체에서 값을 추출해 변수로 넣는 작업입니다. 먼저 구조분해를 사용하지 않는 경우를 살펴보겠습니다.
fun getFullName() = Triple("John", "Quncy", "Adams") // bad!! val result = getFullName() val first = result.first val second = result.second val third = result.third println("$first $second $third")
Java에서는 위와 같이 하나씩 접근해서 값을 가져와야하는 불편함이 있었습니다. 위 코드는 구조분해를 적용해 수정하겠습니다.
// Good!! val (s1, s2, s3) = getFullName() println("$s1 $s2 $s3")
모든 변수를 가져오지 않을 수도 있습니다.
// skip!! val (_, _, s4) = getFullName()
정리
- 사용자가 메소드를 만들도록 강요하지 않음
- 애플리케이션이 반드시 객체로만 이루어질 필요가 없고 함수로 구성이 가능하다. 절차적, 객체지향적, 함수형 코드 중 아무거나 선택 가능
- 컴파일러는 단일 표현식이면서 블록이 없는 함수의 경우 리턴타입을 추론 가능. 파라미터를 정의할 땐 항상 타입이 필요
- 기본인자 기능은 함수를 확장하기 쉽게 가능. 함수를 오버로드 하는 일을 줄임
- 'vararg'는 타입의 안정성을 제공하면서 여러 개의 인자를 넘기는 것을 유연하게 제공
- 스프레드 연산자는 vararg 파라미터에 배열을 넘기는 것을 쉽게 제공
- 명시적 인자를 사용하는 것은 코드의 가독성 향상
- 구조분해는 코드의 방해요소를 줄여주고, 코드가 매우 간결
'Study > kotlin' 카테고리의 다른 글
[코틀린 프로그래밍] Chapter.06 오류를 예방하는 타입 안정성 (0) | 2021.04.20 |
---|---|
[코틀린 프로그래밍] Chapter.05 콜렉션 사용하기 (0) | 2021.04.14 |
[코틀린 프로그래밍] Chapter.04 외부 반복과 아규먼트 매칭 (0) | 2021.04.13 |
[코틀린 프로그래밍] Chapter.02 Java의 개발자를 위한 코틀린 필수 사항 (0) | 2021.03.29 |
[코틀린 프로그래밍] Chapter.01 시작하기 (0) | 2021.03.23 |