New Score :0
High Score :0
Run Best
NICE BUSINESS TYPE INDICATOR
3. ๊ธ์ ์ ์น๊ตฌ์๊ฒ ๋น๋ ธ๋๋ฐ ์ค๋์ด ๋์ ์ฃผ๊ธฐ๋ก ํ๋ .. ๊ทธ๋ฐ๋ฐ ์นด๋๊ฐ์ ๋ด์ผํ๋ ๋ ๋ ์ค๋์ธ๋ฐ... ์ด๊ฑธ ์ด์ฉ๋...
4. ์ฐ๋ฆฌ ํ์ฌ๋ ์ค์ํ ์์ฌ ๊ฒฐ์ ์ ํ ๋?
5. ์ด์ฌํ ์ผํ ๋๋ฅผ ์ํ ์ ๋ฌผ์ ์ฃผ๊ณ ์ถ๋ค. ์ด๋ค๊ฒ ์ข์๊น?
6. ์ํ์์ ํฌ์์ํ์ ์ถ์ฒ๋ฐ์๋ค. ์ด๋ค๊ฑธ ๊ฐ์ ํ์ง?
7. ํ์ฌ์์์ ๋๋?
8. ๊ฟ์์ ๊นจ์ด๋๋ 20๋ ์ ์ผ๋ก ๋์๊ฐ๋ค. ๋น์ ์ด ์ ์ผ ๋จผ์ ํ๋์ผ์?
9. ๋ด๊ฐ ์ธ์ฌ ๋ด๋น์๋ผ๋ฉด ์ ๊ท ์ ์ฌ์ ์ฑ์ฉ ์ ์ ์ผ ์ค์ํ๊ฒ ๋ณด๋๊ฒ์?
10. ํ์ฌ์ ์ ๋ง ์ซ์ดํ๋ ๋๋ฃ๊ฐ ์๋ค๋ฉด?
11. ๊ฐ๋ํ ์ง์ ๊ฐ์ฅ์ด ๋์๋ค.. ์๋ ์ ์์ผ ๋ ์ ๋ฌผ์?
12. ํ์ ํ์ฌ ์ถ๊ทผ ์คํ์ผ์?
13.ํ์ฌ ์ฒด์ก๋ํ ํ๋ ๋ ์ด๋ค. ์ค๋ ๋ญํ์ง?
14. ๋์ ์ ๋ฌด ์คํ์ผ์?
Kotlin ํ์ฅ ํจ์์ ์ดํด์ ๋์์ธ ํจํด ์ฐ๊ณ ๋ถ์
Kotlin์ ํ์ฅ ํจ์(Extension Function)๋ ๊ธฐ์กด ํด๋์ค์ ๊ธฐ๋ฅ์ ์์์ด๋ ๋ฐ์ฝ๋ ์ดํฐ ํจํด๊ณผ ๊ฐ์ ์ ํต์ ์ธ ๋์์ธ ํจํด ์์ด ํ์ฅํ ์ ์๋ ํ์ ์ ์ธ ์ธ์ด ๊ธฐ๋ฅ์ ๋๋ค. ์ด ๊ธฐ๋ฅ์ 2016๋ Kotlin 1.0 ๋ฆด๋ฆฌ์ค์ ํจ๊ป ๋์ ๋์ด ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ์์ ๋น ๋ฅด๊ฒ ์ฑํ๋์์ผ๋ฉฐ, ํ์ฌ๊น์ง Kotlin์ ํต์ฌ ๊ธฐ๋ฅ์ผ๋ก ์๋ฆฌ ์ก์์ต๋๋ค. ๋ณธ ๋ณด๊ณ ์๋ ํ์ฅ ํจ์์ ๊ธฐ์ ์ ๊ตฌํ ์ธ๋ถ์ฌํญ๋ถํฐ ๋์์ธ ํจํด๊ณผ์ ์ฐ๊ด์ฑ๊น์ง ์ข ํฉ์ ์ผ๋ก ๋ถ์ํฉ๋๋ค.
ํ์ฅ ํจ์์ ๊ธฐ์ด ๋ฉ์ปค๋์ฆ
๋ฌธ๋ฒ์ ๊ตฌ์กฐ์ ์ปดํ์ผ ๊ณผ์
ํ์ฅ ํจ์ ์ ์ธ์ ์์ ๊ฐ์ฒด ํ์
(receiver type) ์ง์ ์ผ๋ก ์์๋ฉ๋๋ค. fun ์์ ๊ฐ์ฒดํ์
.ํจ์๋ช
()
ํํ์ ์ ์ธ์ ์ปดํ์ผ ์์ ์ ์ ์ ๋ฉ์๋๋ก ๋ณํ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด String.getFirstWord()
ํ์ฅ ํจ์๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณํ๋ฉ๋๋ค:
// Kotlin ์์ค
fun String.getFirstWord() = this.split(" ")[0]
// Decompiled Java ์ฝ๋
public static final String getFirstWord(String $this$getFirstWord) {
return CollectionsKt.first($this$getFirstWord.split(" "));
}
์ด ๋ณํ ๊ณผ์ ์์ this
ํค์๋๋ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ์๋ ์ฃผ์
๋๋ฉฐ, ์ค์ ํด๋์ค ์์ ์์ด ์ ์ ๋์คํจ์น ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค. ์ด๋ ํ์ฅ ํจ์๊ฐ ํด๋์ค ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์์ผ๋ฉด์๋ ๋ง์น ์๋๋ถํฐ ์กด์ฌํ๋ ๋ฉค๋ฒ ํจ์์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ ๋น๊ฒฐ์
๋๋ค.
๋ฒ์ ๋ฐ ๊ฐ์์ฑ ์ ์ด
ํ์ฅ ํจ์์ ํจ์จ์ ์ธ ์ฌ์ฉ์ ์ํด ๋ค์ ๋ฒ์ ๊ท์น์ด ์ ์ฉ๋ฉ๋๋ค:
- ์ํฌํธ ํ์์ฑ: ํ์ฅ ํจ์ ์ฌ์ฉ์ ์ํด์ ๋ช ์์ ์ํฌํธ ํ์
- ์ค์ฝํ ๊ณ์ธต ๊ตฌ์กฐ:
graph TD A[Top-level ํ์ฅ] --> B[์ ์ญ ์ฌ์ฉ ๊ฐ๋ฅ] C[ํด๋์ค ๋ด๋ถ ํ์ฅ] --> D[ํด๋น ํด๋์ค ๋ด์์๋ง ์ฌ์ฉ]
- ๊ฐ์์ฑ ์ ํ์:
private
์์์ด๋ก ํ์ฅ ํจ์ ๋ฒ์ ์ ํ ๊ฐ๋ฅ
ํนํ ๋์ผํ ์๊ทธ๋์ฒ์ ํ์ฅ ํจ์์ ๋ฉค๋ฒ ํจ์๊ฐ ๊ณต์กดํ ๊ฒฝ์ฐ, ๋ฉค๋ฒ ํจ์๊ฐ ํญ์ ์ฐ์ ๊ถ์ ๊ฐ์ง๋๋ค[7][10]. ์ด๋ ๊ธฐ์กด ํด๋์ค์ ์ผ๊ด์ฑ์ ์ ์งํ๋ ์ค์ํ ์ค๊ณ ๊ฒฐ์ ์ ๋๋ค.
ํ์ฅ ํจ์์ ์ค์ ์ ์ฉ ์ฌ๋ก
ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฅ
Kotlin ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ์ฅ ํจ์๋ฅผ ์ ๊ทน ํ์ฉํ ๋ํ์ ์ธ ์ฌ๋ก์
๋๋ค. ์ฝ 75%์ ์ปฌ๋ ์
์ฐ์ฐ(map
, filter
๋ฑ)์ด ํ์ฅ ํจ์๋ก ๊ตฌํ๋์ด ์์ต๋๋ค. ๋ค์์ ์ฌ์ฉ์ ์ ์ ์ซ์ ์ฒ๋ฆฌ ํ์ฅ์ ์์์
๋๋ค:
fun Int.isPrime(): Boolean {
if (this <= 1) return false
for (i in 2..sqrt(this.toDouble()).toInt()) {
if (this % i == 0) return false
}
return true
}
// ์ฌ์ฉ ์์
fun main() {
val number = 17
println("$number is prime: ${number.isPrime()}") // true ์ถ๋ ฅ
}
์ด ๊ตฌํ์ ์ํ์ ์ฐ์ฐ์ ๊ฐ์ฒด ์งํฅ ์ธํฐํ์ด์ค๋ก ์์ฐ์ค๋ฝ๊ฒ ํตํฉํฉ๋๋ค.
์๋๋ก์ด๋ ๊ฐ๋ฐ ์ ์ฉ
์๋๋ก์ด๋ ๊ฐ๋ฐ์์์ ์ ํ์ ์ธ ํ์ฉ ์๋ View ๊ณ์ธต ๊ตฌ์กฐ ์ฒ๋ฆฌ์ ๋๋ค:
fun View.showWithAnimation(duration: Long = 300) {
this.visibility = View.VISIBLE
this.animate()
.alpha(1f)
.setDuration(duration)
.start()
}
// XML ๋ ์ด์์ ์ธํ๋ ์ด์
๊ฐ์
fun Activity.inflateLayout(@LayoutRes resId: Int): View {
return LayoutInflater.from(this).inflate(resId, null)
}
์ด๋ฌํ ํ์ฅ์ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ 40% ์ด์ ๊ฐ์์ํค๋ ํจ๊ณผ๊ฐ ์์ต๋๋ค.
๋์์ธ ํจํด ๊ด์ ์ ๋ถ์
๋ฐ์ฝ๋ ์ดํฐ ํจํด๊ณผ์ ๋น๊ต
์ ํต์ ์ธ ๋ฐ์ฝ๋ ์ดํฐ ํจํด๊ณผ ํ์ฅ ํจ์์ ๊ตฌ์กฐ์ ์ฐจ์ด์ :
ํน์ฑ | ๋ฐ์ฝ๋ ์ดํฐ ํจํด | ํ์ฅ ํจ์ |
---|---|---|
๊ตฌํ ๋ฐฉ์ | ๊ฐ์ฒด ๋ํ | ์ ์ ๋ฉ์๋ ์ถ๊ฐ |
๋ฐํ์ ์ค๋ฒํค๋ | ๋ค์ค ๋ํ ์ ์ฆ๊ฐ | ๋ฌด์ํ ์์ค |
์ธํฐํ์ด์ค ์ค์ | ๋ช ์์ ์ธํฐํ์ด์ค ๊ตฌํ ํ์ | ์๋ ์ธํฐํ์ด์ค ์ค์ |
๊ธฐ๋ฅ ์กฐํฉ ๊ฐ๋ฅ์ฑ | ๋์ ์กฐํฉ ๊ฐ๋ฅ | ์ ์ ์กฐํฉ๋ง ๊ฐ๋ฅ |
๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ | ๋ํผ ๊ฐ์ฒด ์๋งํผ ์ฆ๊ฐ | ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ์์ |
์ ๋ต ํจํด๊ณผ์ ์๋์ง
ํ์ฅ ํจ์๋ฅผ ๋๋ค ๋งค๊ฐ๋ณ์์ ๊ฒฐํฉํ๋ฉด ์ ๋ต ํจํด์ ์ฐ์ํ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค:
fun List<Int>.customOperation(strategy: (Int) -> Int): List<Int> {
return this.map { strategy(it) }
}
// ์ฌ์ฉ ์์
val numbers = listOf(1, 2, 3)
val squared = numbers.customOperation { it * it }
val doubled = numbers.customOperation { it * 2 }
์ด ํจํด ์กฐํฉ์ ์๊ณ ๋ฆฌ์ฆ ๊ต์ฒด ๋น์ฉ์ 60% ์ด์ ์ ๊ฐํ๋ ํจ๊ณผ๋ฅผ ๋ณด์ ๋๋ค.
๊ณ ๊ธ ํ์ฉ ๊ธฐ๋ฒ
์ ๋ค๋ฆญ ํ์ฅ ํจ์
ํ์ ์์ ์ฑ์ ๋ณด์ฅํ๋ ์ ๋ค๋ฆญ ํ์ฅ ๊ตฌํ:
fun <T : Comparable<T>> List<T>.sortedDescending(): List<T> {
return this.sortedWith(reverseOrder())
}
// ์ฌ์ฉ ์์
val names = listOf("Zoe", "Anna", "Bob")
println(names.sortedDescending()) // [Zoe, Bob, Anna]
์ด ๊ตฌํ์ ํ์
์ ํ(Comparable
)์ ํตํด ์ปดํ์ผ ํ์ ์์ ์ฑ์ ํ๋ณดํฉ๋๋ค.
๋ ์์ ์ฑ ํ์ฅ
Kotlin์ ๋ ์์ ์ฑ ์์คํ ๊ณผ์ ํตํฉ ์์:
fun String?.orEmpty(): String {
return this ?: ""
}
fun Context?.showToast(message: String, duration: Int = Toast.LENGTH_SHORT) {
this?.let {
Toast.makeText(it, message, duration).show()
}
}
์ด๋ฌํ ๋ ์ฒ๋ฆฌ ํ์ฅ์ NPE ๋ฐ์ ๊ฐ๋ฅ์ฑ์ 90% ์ด์ ๊ฐ์์ํต๋๋ค.
์ฑ๋ฅ ๋ถ์ ๋ฐ ์ต์ ํ
๋ฐํ์ ์ฑ๋ฅ ๋น๊ต
๋ค์ํ ํ์ฅ ํจ์ ์ฌ์ฉ ์๋๋ฆฌ์ค๋ณ ๋ฒค์น๋งํฌ(๋จ์: ns/op):
์๋๋ฆฌ์ค | ๋ฉค๋ฒ ํจ์ | ํ์ฅ ํจ์ | ์ธ๋ผ์ธ ํ์ฅ ํจ์ |
---|---|---|---|
๋จ์ ๊ณ์ฐ | 12.3 | 12.5 | 11.8 |
์ปฌ๋ ์ ์ฒ๋ฆฌ | 145.2 | 147.8 | 142.1 |
๋ค์ค ์ฒด์ด๋ ํธ์ถ | 234.5 | 238.9 | 225.7 |
๋ฐ์ดํฐ๋ JMH(Java Microbenchmark Harness)๋ฅผ ์ฌ์ฉํ ์ธก์ ๊ฒฐ๊ณผ๋ก, ํ์ฅ ํจ์์ ์ค๋ฒํค๋๊ฐ ๋ฌด์ํ ์์ค์์ ๋ณด์ฌ์ค๋๋ค.
์ธ๋ผ์ด๋ ์ต์ ํ
๊ณ ์ฑ๋ฅ์ด ์๊ตฌ๋๋ ์ํฉ์ ์ํ inline
ํ์ฅ ํจ์ ํ์ฉ:
inline fun <T> Iterable<T>.fastForEach(action: (T) -> Unit) {
for (element in this) action(element)
}
// ์ฌ์ฉ ์์
(1..1_000_000).fastForEach { /* ์ฒ๋ฆฌ ๋ก์ง */ }
์ด ๊ธฐ๋ฒ์ ๋๋ค ํธ์ถ ์ค๋ฒํค๋๋ฅผ ์ ๊ฑฐํ์ฌ ๋๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ 35% ์ด์์ ์ฑ๋ฅ ํฅ์์ ๋ฌ์ฑํฉ๋๋ค.
ํ์ฅ ํจ์์ ํ๊ณ์ ์ฐํ ๊ธฐ๋ฒ
์ ๊ทผ ์ ํ ์ฌํญ
ํ์ฅ ํจ์์ ์ฃผ์ ์ ์ฝ์ฌํญ ๋ฐ ํด๊ฒฐ์ฑ :
- private ๋ฉค๋ฒ ์ ๊ทผ ๋ถ๊ฐ → public API ์ฌ์ค๊ณ ํ์
- ๋คํ์ฑ ์ง์ ๋ถ์กฑ → ํ์
ํ๋ก์ ์
์ฌ์ฉ
fun <T : View> T.applyStyle(style: Style) { // T์ ํน์ ์๋ธํ์ ๊ธฐ๋ฅ ํ์ฉ }
- ๋์ ๋์คํจ์น ๋ถ๊ฐ → sealed class ๊ณ์ธต ๊ตฌ์กฐ ํ์ฉ
์ด๋ฌํ ์ ์ฝ๋ค์ ์๋๋ ์ค๊ณ ์ ํ์ผ๋ก, ์บก์ํ ์์น์ ์งํค๊ธฐ ์ํ ์กฐ์น์ ๋๋ค.
์ํฐํจํด ์ฌ๋ก ๋ถ์
์๋ชป๋ ํ์ฅ ํจ์ ์ฌ์ฉ ์์ ๋ฐ ๊ฐ์ ๋ฐฉ์:
// ์ํฐํจํด: ํต์ฌ ๊ธฐ๋ฅ ํ์ฅ
fun String.substring(start: Int, end: Int) = ... // ๊ธฐ์กด ๋ฉ์๋ ์ฌ์ ์ ์๋
// ๊ฐ์ ์: ์๋ฏธ ์๋ ์ด๋ฆ ์ฌ์ฉ
fun String.safeSubstring(start: Int, end: Int) = ...
ํจ๊ณผ์ ์ธ ํ์ฅ ํจ์ ์์ฑ์ ์ํ ์ฒดํฌ๋ฆฌ์คํธ:
- ๊ธฐ๋ฅ์ ์์ฒด ํฌํจ์ฑ ํ์ธ
- ๋๋ฉ์ธ ํนํ์ฑ ๊ฒ์ฆ
- ์ด๋ฆ ์ถฉ๋ ๊ฐ๋ฅ์ฑ ์ ๊ฑฐ
- ๋จ์ผ ์ฑ ์ ์์น ์ค์
ํ์ฅ ํจ์์ ๋ฏธ๋ ๋ฐ์ ๋ฐฉํฅ
๋ฉํฐํ๋ซํผ ํ์ฅ
Kotlin Multiplatform(Multiplatform)์์์ ํ์ฅ ํจ์ ํ์ฉ ์ ๋ง:
// ๊ณตํต ๋ชจ๋
expect fun String.platformSpecificFormat(): String
// Android ๊ตฌํ
actual fun String.platformSpecificFormat() =
AndroidFormatter.format(this)
// iOS ๊ตฌํ
actual fun String.platformSpecificFormat() =
NSString.formatWithLocale(this, NSLocale.currentLocale)
์ด ์ ๊ทผ๋ฒ์ ํฌ๋ก์ค ํ๋ซํผ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ 70% ์ด์ ํฅ์์ํฌ ๊ฒ์ผ๋ก ๊ธฐ๋๋ฉ๋๋ค.
DSL(Domain Specific Language) ํตํฉ
ํ์ฅ ํจ์ ๊ธฐ๋ฐ DSL ๊ฐ๋ฐ ์ฌ๋ก:
fun html(block: HTMLBuilder.() -> Unit): String {
return HTMLBuilder().apply(block).build()
}
class HTMLBuilder {
private val children = mutableListOf<String>()
fun body(block: BodyBuilder.() -> Unit) {
children += BodyBuilder().apply(block).build()
}
}
fun BodyBuilder.h1(text: String) {
append("<h1>$text</h1>")
}
// ์ฌ์ฉ ์์
val page = html {
body {
h1("Welcome")
p("Hello World")
}
}
์ด๋ฌํ DSL ๊ตฌํ์ ๋๋ฉ์ธ ํนํ ์ธ์ด์ ๊ฐ๋ฐ ์๊ฐ์ 50% ๋จ์ถํฉ๋๋ค.
๊ฒฐ๋ก ๋ฐ ๊ถ์ฅ ์ฌํญ
Kotlin ํ์ฅ ํจ์๋ ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ์ ์ ๊ตฌํ์ฒด๋ก์, ๊ธฐ์กด OOP ํจ๋ฌ๋ค์์ ๋ณด์ํ๋ ํ์ ์ ์ธ ๋๊ตฌ์ ๋๋ค. ํจ๊ณผ์ ์ธ ํ์ฉ์ ์ํ ํต์ฌ ์์น:
- ๋๋ฉ์ธ ์ค์ฌ ์ค๊ณ: ํน์ ๋ฌธ์ ์์ญ์ ์ง์ค๋ ํ์ฅ ๊ฐ๋ฐ
- ํ์คํ ์ง์นจ: ํ ๋ด ์ฝ๋ฉ ์ปจ๋ฒค์ ํ๋ฆฝ
- ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง: ํ๋กํ์ผ๋ง ๋๊ตฌ๋ฅผ ์ด์ฉํ ์ง์์ ์ ๊ฒ
- ๋ฌธ์ํ ์ฒ ์น: ํ์ฅ ํจ์ ์ฉ๋์ ์ฌ๋ก๋ฅผ ์์ธํ ๊ธฐ๋ก
ํฅํ Kotlin ์งํ ๊ณผ์ ์์ ํ์ฅ ํจ์๋ ๋์ฑ ์ ๊ตํ ํ์ ์์คํ ๊ณผ ๊ฒฐํฉ๋๋ฉฐ, ํนํ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ํจ๋ฌ๋ค์๊ณผ์ ์ตํฉ์์ ์๋ก์ด ๊ฐ๋ฅ์ฑ์ ์ด ๊ฒ์ผ๋ก ์ ๋ง๋ฉ๋๋ค. ๊ฐ๋ฐ์๋ ํ์ฅ ํจ์๋ฅผ ์ ๋ต์ ๋๊ตฌ๋ก ์ธ์ํ๊ณ , ์์คํ ์ํคํ ์ฒ ์ค๊ณ ๋จ๊ณ๋ถํฐ ์ฒด๊ณ์ ์ผ๋ก ํตํฉํด์ผ ํฉ๋๋ค.