첫번째 코틀린 모임이 강남소재의 교육 스타트업인 Riiid 사무실에서 있었습니다. Riiid 는 데이터 기술을 통해 교육기회의 평준화를 목표로 하는 스타트업입니다. 이 모임 발표중 해재위님이 간단한 예제로 Kotlin 기능 소개를 해주신 세션영상을 정리하여 공개합니다
이 모임은 교육 스타트업인 Riiid(뤼이드)에서 안드로이드 개발자로 근무하고 계신 허재위 님 사회로 진행되었습니다. 아래 개요를 정리하였지만 동영상에서 데모와 함께 매우 쉽게 설명되어있으니 동영상을 보시는 것을 추천드립니다.
익스텐션
익스텐션은 기존의 객체에 원하는 동작을 추가로 삽입합니다.
public fun <T> List<T>.getOrNull(index: Int): T? {
return if (index >= 0 && index <= lastIndex) get(index) else null
}
위의 코드는 기존 List<T>
에 메서드 getOrNull
을 넣은 것이고요. 범위가 맞지 않으면 null
을 반환하는 것입니다. 기존의 코드에 여러가지 내용을 추가하면 전체적인 프로그래밍에 효율적으로 사용할 수 있습니다.
join
을 구분자(separator)에 인자를 붙여 쓰고 싶을 때에는 아래와 같이 사용할 수 있습니다.
fun String.join(vararg strings: String): String =
strings.joinToString(separator = this)
데이터 클래스
data class
의 생성자에 기술된 모델 정보를 가지고 equal
과 hashCode
등의 메서드를 자동으로 생성해주기 때문에 유용합니다. 이런 특징은 Rx를 사용할 때 더 빛이 납니다.
유틸리티
let
let
은 값이 있는 경우에 다른 코드 블록을 추가로 수행하는 것입니다.
override fun onBindViewHolder(holder: RepoViewHolder?, position: int) {
repos.getOrNull(position)?.let {
holder?.setRepo(it)
}
}
만약에 getOrNull
의 반환값을 받아 비교하고 참인 경우에 그 변수를 쓴다고 생각하면 코드가 좀 더 번잡해집니다. 파라미터가 없으면 it
으로 전달되기 때문에 간단히 결과값을 사용할 수 있습니다.
apply
생성자를 확장할 방법은 마땅치 않습니다. 초기화 과정이 필요할 때 apply
를 사용해봅시다.
private fun initHttpLoggingIntercepter(): HttpLoggingIntercepter {
return HttpLoggingIntercepter().apply {
level = if (BuildConfig.DEBUG) {
HttpLoggingIntercepter.Level.BODY
} else {
HttpLoggingInterceptor.Level.NONE
}
}
}
level
은 HttpLoggingIntercepter
인스턴스의 level
멤버변수입니다. 멤버변수의 초기화나 초기에 호출할 메서들들을 한번에 모아 일목요연하게 다룰 수 있습니다.
run
어떤 경우에는 어떤 인스턴스에 관련된 필드나 메서드에 연속적으로 접근해야할 때가 있습니다. 이런 경우 run
을 쓸 수 있습니다.
class RepoViewHolder(private val view: View): RecyclerView.ViewHolder(view) {
fun setRepo(repo: Repository) {
view.run {
findViewById(R.id.fg).setOnClickListener {
val message = repo.run {
"\n".join(fullName, language)
}
Toast.makeText(view.context, message, Toast.LENGTH_SHORT).show()
}
...
}
}
}
view.run
키워드 이후에 view
내의 필드나 메서드에 대한 접근이 암묵적으로 허용이 됩니다. view.findViewById(R.id.fg)
대신에 findViewById(R.id.fg)
를 쓸 수 있습니다. 마찬가지로 repo.run
이후로 repo
에 속한 repo.fullName
과 repo.language
를 자연스럽게 쓸 수 있습니다.
lazy
처음에 null
을 넣고 나중에 초기화를 시켰던 경우도 있습니다. 초기화 포인트를 여러 곳에 분리시켜서 불편하셨다면 lazy
키워드를 이용할 수 있습니다.
private val adapter by lazy { RepoAdapter(this) }
위의 코드는 adapter
가 실제로 사용이 되어야 할 때 뒤 늦게 RepoAdapter(this)
를 대입합니다.
lateinit
?.
엘비스 연산자를 통해 널인 경우와 아닌 경우를 구분하는 것은 null
반환값이 있는 경우엔 유용하지만 그 값이 null
일 가능성이 없는 경우에도 굳이 써야 할까라는 의문이 들 수 있습니다. 만약에 뒤늦게 값이 대입되어서 절대 null
값을 참조할 가능성이 없다면 변수에 lateinit
를 붙여 나중에라도 null
이 아닐 것임을 알릴 수 있습니다.
Resources
- 발표에 대한 소개와 코드는 깃헙 페이지에서 확인하세요.
컨텐츠에 대하여
이 컨텐츠는 저자의 허가 하에 이곳에서 공유합니다.