단독함수를 이용하는 이유는,
1)코틀린에서 재사용 가능한 탑 레벨 단독함수를 만들면 클래스에서 시간과 노력을 낭비하지 않는다.
2)함수는 클래스의 메소드보다 뛰어난 능력을 가지고 있다. (메소드는 클래스/객체의 컨텍스트에서 동작하는 함수)
Java의 메소드 만드는 방법과는 많은 차이가 있다.
여기서 KISS (Keep It Simple, Stupid) 원칙이라는 게 있다는 걸 처음 알았다. ㅎㅎㅎ
fun greet() : String = "Hello"
-> 함수 리턴타입 추론은 바디가 single expression이고, {} 블록이 아닐 때만 가능, 리턴 타입 앞에는 :를 붙이고 파라미터 리스트를 뒤에 작성한다.
return 키워드는 단일표현식 함수이고, 바디가 블록이 아니라면 허용되지 않음!
리턴타입이 명확하다면 타입 추론을, 아니라면 리턴타입을 명시해주도록!
"표현식은 많게, 명령문은 적게!"
코틀린은 함수에 리턴이 없으면 Unit (Java의 void와 대응) 타입을 리턴 타입으로 추론
println() 리턴값은 자바에서는 void, 코틀린에서는 Unit
리턴 타입을 생략하고, =를 사용해 단일 표현식 대신 블록바디를 사용한다면
코틀린은 코드 블록 안으로 들어가서 리턴타입을 추론하지 않는다. 블록을 람다표현식이나 anonymous function(익명함수) 취급할 것이다.
ex> fun notReally() = {2}
저자분이 상당히 독설적이시다 ㅋㅋㅋㅋ
Named argument는 읽기 좋은 코드를 만드는 아주 유용한 방법이다!
일반 파라미터는 값이 항상 필요해서, 호출하는 쪽에서는 기본 아규먹트에도 값을 무조건 넣어줘야 한다. -> 이런 행위는 기본 아규먼트를 무의미하게 만든다!
함수가 명시적 아규먼트를 사용한다면 호출하는 쪽에서는 기본 아규먼트를 생략할 수 있다.
기본 아규먼트는 마지막에 위치하는 람다표현식의 파라미터 자리 바로 앞에 올 수 있다.
명시적 아규먼트는 함수 정의는 손대지 않고, 최소한의 노력으로 호출 부분에서 메소드를 가독성 좋게 바꾸기 위해 사용된다.
*명시적 아규먼트는 순서와 상관없이 사용 가능!
명시적 아규먼트는 메소드 호출 부분의 가독성을 높여줌.
또한, 함수 변경으로 인한 파라미터 추가 시 함수에 발생할 수 있는 잠재적 오류의 가능성을 제거!
파라미터 전달 시 의미가 명확하지 않으면 명시적 아규먼트를 사용하자
vararg를 사용하면 하나 이상의 파라미터를 취급할 수 있다.
단, 함수에서 하나의 파라미터에서만 사용할 수 있다.
vararg 사용 시 위치에 대한 권장사항
1.vararg는 마지막에 두어서 호출 시 명시적 인자를 필수적으로 사용할 필요가 없도록 만들자.
2.마지막 파라미터가 람다표현식일 경우 마지막 바로 전에 둔다.
vararg를 사용하면 함수에 전달인자가 많을 때 쉽게 처리할 수 있지만,
이미 배열이 있다면 스프레드 연산자를 사용해 볼 수 있다 !
배열이나 리스트에 있는 값들을 vararg 인자로 함수에 전달해야 하는 경우,
함수가 다중 인자를 받을 수 있도록 정의되어 있지민 배열이나 리스트를 직접 받을 수는 없다.
이럴 때 스프레드 연산자를 사용한다!
print( max(value[0], value[1], value[2] ))
- 너무 장황하다
print(max(*values))
- *values를 통해 배열 값을 추출, vararg 파라미터에 다중인자로 넘기라고 요청함
구조화 : 다른 변수의 값으로 객체를 만드는 것
구조 분해 : 그 반대, 이미 존재하는 객체에서 값을 추출해 변수로 넣는 작업
Triple (튜플을 구현하는 코틀린 스탠다드 라이브러리)
fun getFullName() = Triple("John", "Quincy", "Adams")
val result = getFullName()
val first - result.first
val middle - result.second
val last - result.third
println("$first $middle $last")
⬇️ 구조 분해 사용
val (first, middle, last) = getFullName()
println("$first $middle $last")
- getFullName() 함수가 순서대로 여러 값을 할당했다.
만약 리턴된 오브젝트 중 필요없는 속성이 있다면, 언더스코어(_)로 스킵하면 된다!