val request =AstroRequest()val result = request.execute()println(result.message)
이 접근 방식에는 아무 문제가 없지만 AstroRequest 클래스의 목적은 오직 하나이므로 해당 함수의 이름을 invoke로 변경하고 operator 키워드를 추가해 다음과 같이 실행시킬 수 있다.
internalclassAstroRequestTest {val request =AstroRequest()@Testinternalfun`get people in space`() {val result =request(2)asssertThat(result.message, `is`("success")) }}
이처럼 invoke 연자라 함수를 제공하고 클래스 레퍼런스에 괄호를 추가하면 클래스 인스턴스를 바로 실행할 수 있다. 원한다면 필요한 인자를 추가한 invoke 함수 중복도 추가할 수 있다.
경과 시간 측정하기
코드 블록이 실행되는 데 걸린 시간을 알고 싶을 경우 measureTimeMillis 또는 mearueNanoTime 함수를 사용한다.
fundoubleIt(x: Int): Int { Thread.sleep(100L)println("doubling $x with on thread %{Thread.currentThread().name}")return x *2}funmain() {println("${Runtime.getRuntime().availableProcessors()} processors")var time =measureTimeMillis { IntStream.rangeClosed(1, 6) .map { doubleIt(it) } .sum() }}
start 인자의 기본값이 true이므로 다음 예제처럼 다수의 스레드를 쉽게 생성하고 시작할 수 있다.
(0..5).forEach { n ->val sleepTime = Random.nextLong(range =0..1000L)thread { Thread.sleep(sleepTime)println("${Thread.currentThread().name} for $n after ${sleepTime}ms") }}
이 코드는 6개의 스레드를 시작하고, 각 스레드는 0부터 1000 사이에서 무작위로 결정된 밀리초 동안 sleep한 다음 해당 스레드의 이름을 출력한다.
thread 함수의 start 파라미터 기본값이 true 이므로 각 스레드마다 start를 호출할 필요가 없다.
TODO로 완성 강제하기
개발자가 특정 함수나 테스트를 강제로 구현할 수 있도록 TODO 함수를 사용해라
개발자는 종종 어떤 시점에 구현을 완료할 준비가 되지 않은 함수를 완성하기 위해 그들 스스로 메모를 남겨 놓는다. 대부분의 언어에서는 다음 예제처럼 TODO 문을 주석에 추가한다.
funmyCleverFunction() {// TODO: 멋진 구현을 찾는 중}
코틀린 표준 라이브러리에는 TODO라는 함수가 있는데 이 함수는 다음과 같이 구현되어 있다.
publicinlinefunTODO(reason: String): Nothing=throwNotImplementedError("An operation is not implemented: $reason")
효율성을 이유로 소스는 인라인되어 있고 함수가 호출될 때 NotImplementedError를 던진다.
funmain() {TODO(reason ="none, really")}
함수 이름에 특수 문자 사용하기
함수 이름을 읽기 쉽게 작성하고 싶을 경우엔 함수 이름을 백틱으로 감싸 읽기 쉽게 만들 수 있다. 하지만 이 기법은 테스트에서만 사용하자
fun`인철 짱`() {println("인철 짱")}funmain() {`인철 짱`()}
위 처럼 사용하게 되면 함수 이름에 띄어쓰기도 사용할 수 있고 테스트 메소드의 경우에는 어떤 테스트의 메소드를 실행하였는지 더 명확하게 전달되어서 가독성을 높여준다.
자바에게 예외 알리기
코틀린 함수가 자바에서 체크 예외로 예외를 던지는 경우에는 @Throws 애노테이션을 추가하면 알릴 수 있다.
코틀린의 모든 예외는 언체크 예외다. 즉 컴파일러는 개발자에게 해당 예외를 처리할것을 요구하지 않는다. 예외를 붙잡기 위해 코틀린 함수에 try/catch/finally 블록을 추가하는 방법은 아주 쉽지만 강제사항은 아니다.
funhousonWeHaveAProblem() {throwIOException("File or resource not found")}public static void doNothing() {housonWeHaveAProblem()}
그러나 둘 중 어느 방식도 원하는 대로 동작하지 않는다. 명시적으로 try/catch 블록 추가를 시도하면 자바는 catch 블록 안에 명시된 IOException이 연관된 try 블록 내에서 해당 예외를 절대 던지지 않는다고 생각하기 때문에 코드가 컴파일되지 않는다. 두 번째 throws 절을 추가하는 경우에는 코드가 컴파일되지만 IDE는 '불필요한' 코드가 있다고 경고할 것이다.
두 가지 해결방법을 동작하게 만드는 방법은 다음과 같이 @Throws 애노테이션을 코틀린 코드에 추가하는 것이다.
@Throws(IOException::class)funhousonWeHaveAProblem() {throwIOException("File or resource not found")}
이제 자바 컴파일러는 IOEception을 대비해야 한다는 것을 안다. @Throws 애노테이션은 그저 자바/코틀린 통합을 위해서 존재한다.