μ λ€λ¦μ€λ₯Ό μ°λ©΄ νμ νλΌλ―Έν°λ₯Ό λ°λ νμ μ μ μν μ μλ€.(List, Map κ³Ό κ°μ)
μ½νλ¦°μ κ°μ΄ λ€μ΄μ€λ κ²μ λ°λΌ νμ μΈμλ₯Ό μΆλ‘ ν μ μλλ°, λΉλ¦¬μ€νΈλ₯Ό λ§λ€ κ²½μ°μλ νμ μΈμμ νμ μ λͺ μν΄μ€μΌνλ€. μλ°μμλ μ²μλΆν° μ λ€λ¦μ΄ μμκΈ°μ νμ μΈμλ₯Ό λͺ μνμ§μκ³ μ μΈνλκ² κ°λ₯νμ§λ§ μ½νλ¦°μ μ²μλΆν° μ λ€λ¦μ΄ λμ λΌμ μΆλ‘ μ νκ² νλκ°, λͺ μλ₯Ό ν΄μΌνλ€.
μ λ€λ¦ ν¨μμ νλ‘νΌν°
λͺ¨λ νμ μΈμλ₯Ό κ°λ 리μ€νΈλ₯Ό λ€λ£° μ μλ ν¨μλ₯Ό μμ±νλ©΄, λ°λμ νΈμΆμμ μ ꡬ체μ μΈ νμ μ νμ μΈμλ‘ λ겨μ€μΌνλ€.
fun <T> List<T>.slice(indices: IntRange) : List<T>
λ°ν κ°λ μ λ€λ¦, νμ μΈμλ μ λ€λ¦μ΄λ€. μμ κ°μ²΄λ₯Ό μ΄μ©ν ν¨μλ‘ μ μλμ΄ μλ€.
μ λ€λ¦ ν΄λμ€λ λ§μ°¬κ°μ§λ‘ <T>λ₯Ό μ΄μ©ν΄ μ μΈνλ€.
interface Comparable<T> {
fun compareTo(other: T): Int
}
class String : Comparable<String> {
override fun compareTo(other: String): Int = /*...*/
}
ν΄λμ€μμ Comparable μΈν°νμ΄μ€λ₯Ό ꡬννλλ°, Tμ Stringμ λ£μ΄μ ꡬννλ€.
νμ νλΌλ―Έν° μ μ½
μ΄λ€ νμ μ μ λ€λ¦ νμ μ νμ νλΌλ―Έν°μ λν μνμΌλ‘ μ§μ νλ©΄ κ·Έ μ λ€λ¦ νμ μ μΈμ€ν΄μ€νν λ μ¬μ©νλ νμ μΈμλ λ°λμ κ·Έ μν νμ μ΄κ±°λ κ·Έ μν νμ μ νμ νμ μ΄μ΄μΌ νλ€. μνμΌλ‘ μ§μ νλ€λ μκΈ°λ Numberκ°μ μ΅μμ νμ μ μ§μ ν λλ₯Ό λ§νλ€.
fun <T : Number> oneHalf(value: T): Double {
return value.toDouble() / 10.0
}
μνμ μ§μ νλ©΄ μ΄λλΆν° Tλ μννμ μΌλ‘ λ³νλ€.
μ΄λ° μ μ½μ λ¨μΌ μ μ½μ΄κ³ , μ¬λ¬ μ μ½μ μ μ©νκ³ μΆμΌλ©΄ νμ νλΌλ―Έν° μ μ½ λͺ©λ‘μ μ¬μ©νλ©΄ λλ€.
fun <T> ensureTrailingPeriod(seq: T)
where T : CharSequence, T : Appendable { // <- μ΄ λΆλΆμ 쑰건 κ²μ¬κ° λͺ©λ‘μν ν¨
}
non-null νμ μΌλ‘ νμ νλ λ²λ μλ€. μνμ μ νμ§μμ νμ νλΌλ―Έν°λ Any?κ° λν΄νΈμΈλ°, κ·Έλ¬λ©΄ nullableμ΄ κΈ°λ³Έμ΄λ€. νμ non-nullλ§ μΈμλ‘ λ°κ²νλ €λ©΄ Anyλ₯Ό λͺ μμ μΌλ‘ μ¨μ μνμ μ§μ νλ©΄λλ€.(Anyκ° μλμ΄λ non-null typeμΌλ‘ μνμ μ§μ νλ©΄λλ€.)
κ·Έλ¬λ©΄ String?, Int?λ Any?μ μμνμ μ΄μ§ Anyμ μμνμ μ΄ μλκΈ° λλ¬Έμ nullμ΄ λ€μ΄μ€μ§ λͺ»νκ² λ§λ€ μ μλ€.
μ€ν μ μ λ€λ¦μ€ λμ
JVMμ μ λ€λ¦μ€λ νμ μκ±°(type erasure)λ₯Ό μ¬μ©ν΄ ꡬνλλ€. μ€νμμ μ μ λ€λ¦ ν΄λμ€μ μΈμ€ν΄μ€μ νμ μΈμ μ λ³΄κ° μ‘΄μ¬νμ§μλλ°, μ΄κ±Έ inlineν¨μλ₯Ό μ΄μ©ν΄ νμ μΈμκ° λ°νμμμ μ μ§μμ§μ§ μκ² νλ κ²μ μ€μ²΄ν(reify)λΌκ³ νλ€. νμ μκ±°μ μ₯μ μΌλ‘λ μ μ₯ν΄μΌνλ νμ μ 보 ν¬κΈ°κ° μ€μ΄μ λ©λͺ¨λ¦¬ μ¬μ©λμ μ€μΈλ€λ κ²μ΄ μλ€.
μ€νμμ μ μ λ€λ¦μ€ μΈμ€ν΄μ€λ κ·Έ μ체λ‘λ§ μκ³ , μ΄λ€ μμνμ μ κ°λμ§λ μ»΄νμΌλ¬κ° μ 보μ₯ν΄μ€λ€.
μ΄λ²μ νλ‘μ νΈ λ¦¬ν©ν λ§νλ©΄μ μμ£Ό λ³Έ μλ¬μΈλ°
if (value is List<String>) { ... }
ERROR: Cannot check for instance of erased type
νμ μκ±°λ‘ μΈν΄ is κ²μ¬μμ νμ μΈμλ‘ μ§μ ν νμ μ μ€νμμ μμ κ²μ¬ν μ μκΈ° λλ¬Έμ λ°μνλ μλ¬λ€. μ΄κ±Έ μ¬λ°λ₯΄κ² κ³ μΉλ €λ©΄
if (value is List<*>)
νμ μΈμ νμ μ *(μ€ννλ‘μ μ )μΌλ‘ λ°κΏμΌνλ€. as μΊμ€ν μμλ λΉλλ νμ©νμ§λ§ κ²½κ³ λ¬Έκ΅¬κ° unchecked castλΌκ³ λμ€κΈ΄νλ μ£Όμν΄μΌνλ€.
μ€μ²΄ν
μ λ€λ¦ ν¨μμ λ³Έλ¬Έμμ κ·Έ ν¨μμ νμ μΈμλ₯Ό κ°λ¦¬ν¬μ μκ² νλ λ°©λ²μΌλ‘ inline ν¨μκ° μλ€. μ΄κ² μΈλΌμΈ ν¨μκ° μ μ©ν μ΄μ μ€ νλμΈ νμ μΈμ μ€μ²΄νμ΄λ€.
μ λ€λ¦ ν¨μλ₯Ό μΈλΌμΈ ν¨μλ‘ λ§λ€κ³ , νμ νλΌλ―Έν°λ₯Ό reifiedλ‘ μ§μ νλ©΄ μ€νμμ μ νμ κ²μ¬κ° κ°λ₯νλ€.
inline fun <reified T> isA(value: Any) = value is T
μ»΄νμΌλ¬λ μΈλΌμΈν¨μμ λ³Έλ¬Έμ λ°μ΄νΈμ½λλ‘ λ³νν΄μ νΈμΆ μ§μ μ λ€ λΆμ¬λ²λ¦°λ€. μ΄λ reifiedλ μΈμλ₯Ό νΈμΆ μ§μ μμ λ€ μ μ μκΈ° λλ¬Έμ μ€νμμ μ νμ κ²μ¬κ° κ°λ₯νλ€.
java.lang.Class νμ μΈμλ₯Ό λ°λ κ²½μ° μ€μ²΄νλ₯Ό μμ£Ό μ¬μ©νλ€.
ClassName::class.javaλ‘ νλΌλ―Έν°μ λ£λ κ²½μ°μΈλ°, μ΄κ±Έ inlineκ³Ό reifiedλ₯Ό μ΄μ©ν΄ λ°κΏλ³΄λ©΄ μλμ κ°λ€.
inline fun <reified T: Activity> Context.startActivity() {
val intent = Intent(this, T::class.java)
startActivity(intent)
}
::λ ν΄λμ€ μ°Έμ‘°ν λ μ¬μ©νλλ°, 10μ₯μ 리νλ μ λ μμΈν λμ¨λ€κ³ νλ€.
μ€μ²΄νλ νμ§ λͺ»νλ κ² μλ€.
- νμ νλΌλ―Έν° ν΄λμ€μ μΈμ€ν΄μ€ μμ±
- νμ νλΌλ―Έν° ν΄λμ€μ λλ° κ°μ²΄ λ©μλ νΈμΆ
- μ€μ²΄νν νμ νλΌλ―Έν°λ₯Ό μꡬνλ ν¨μλ₯Ό νΈμΆνλ©΄μ μ€μ²΄ννμ§ μμ νμ νλΌλ―Έν°λ‘ λ°μ νμ μ νμ μΈμλ‘ λκΈ°κΈ°
- ν΄λμ€, νλ‘νΌν°, μΈλΌμΈ ν¨μκ° μλ ν¨μμ νλΌλ―Έν°λ₯Ό reifiedλ‘ μ§μ νκΈ°(μ΄κ±΄ μ΄λ μ λ μμνλ€)
λ§μ§λ§ μ μ½μ΄ μμΌλ―λ‘, μ±λ₯μμ μ΄μ λ μΈλΌμ΄λλλ κ³Όμ μμ λλ€λ₯Ό μΈλΌμ΄λν μ μλ€λ©΄ noinlineμ λΆμ¬μ μΈλΌμ΄λμ κΈμ§ ν μ μλ€.
λ³μ± variance - 무곡λ³, 곡λ³μ±, λ°κ³΅λ³μ±
base νμ μ΄ κ°κ³ νμ μΈμκ° λ€λ₯Έ μ¬λ¬νμ μ΄ μ΄λ€ κ΄κ³μ λμ¬μλμ§ μμ보λ μ μ΄λ€.
μμ λ³κ²½μ΄ μκΈ΄λ€λ©΄ List<String> -> List<Any> κ³Όμ μμ νμ λΆμΌμΉκ° μκΈΈ μ μμ΄μ λΆκ°λ₯νλ€. κ·Έκ² μλλΌλ©΄ μμ νλ€.
μ λ€λ¦μ΄ μλ ν΄λμ€μ κ²½μ° νμ μ΄ λ μ μλ€. κ·Έ μμλ‘ String ν΄λμ€λ String, String? λ νμ μ΄ λ μ μλ€. μ λ€λ¦ ν΄λμ€μΈ κ²½μ° νμ νλΌλ―Έν°λ₯Ό ꡬ체μ μΈ νμ μΈμλ‘ λ°κΏμ€μΌνλ©° Listλ νμ μ΄ λ μ μμ§λ§ μ¬μ ν ν΄λμ€μ΄κ³ , List<String>κ³Ό κ°μ κ²½μ°λ νμ μ΄λ€.
μν κ°λ μμ λ΄λ €μμ, μ»΄νμΌλ¬λ λ³μλμ / ν¨μμΈμ μ λ¬ μ νμ νμ κ²μ¬λ₯Ό λ§€λ² μννλ€. μ΄λ 보ν΅μ κ²½μ°λ νμνμ == νμ ν΄λμ€ μ΄μ§λ§(non-null -> nullableκ°λ₯, κ·Έ λ°λλ λΆκ°λ₯) μ λ€λ¦ ν΄λμ€μ κ²½μ°λ₯Ό 보μ.
μΈμ€ν΄μ€ν ν λ MutableList<A> MutableList<B>μμ Aμ Bμ μ¬λΆμ λ°λΌ νμνμ κ΄κ³κ° μ±λ¦½νμ§μλ κ²½μ° κ·Έλ μ λ€λ¦ νμ μ 무곡λ³(invariant)μ΄λΌκ³ νλ€.
λ€μ λ§νλ©΄ Bκ° Aμ νμνμ μ΄μ§λ§ MutableList<B>λ MutableList<A>μ νμνμ μ΄ μλ κ²μ 무곡λ³μ΄λΌκ³ νλ€.
List<T>μ κ²½μ°μλ μ½νλ¦°μμ μ½κΈ°μ μ© μ»¬λ μ μΈλ°, List<A>, List<B>λ νμνμ κ·μΉμ μ μ©ν μ μκ³ μ΄λλ 곡λ³(covariant)μ μ΄λΌκ³ λ§νλ€.
μ λ€λ¦ ν΄λμ€(μΈν°νμ΄μ€λ λΉμ°ν ν¬ν¨)κ° νμ νλΌλ―Έν°μ λν΄ κ³΅λ³μ μμ λνλ΄λ €λ©΄ νλΌλ―Έν° μμ outμ νκΈ°ν΄μΌνλ€. μ΄κ² 곡λ³μ μ΄λΌκ³ μ μΈνλ λ°©λ²μ΄λ€.
interface Producer<out T> {
fun produce(): T
}
νμ νλΌλ―Έν°λ₯Ό 곡λ³μ μΌλ‘ λ§λ€λ©΄ μ΄ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό ν¨μ μΈμλ λ°νκ°μΌλ‘ μ¬μ©νλ κ² κ°λ₯ν΄μ§λ€.
λͺ¨λ κ³³μ 곡λ³μ μΌλ‘ λ§λ€κ³ μΆμ§λ§ 곡λ³μ μΌλ μμ νμ§ λͺ»ν κ²½μ°κ° μλ€. νμ νλΌλ―Έν°λ₯Ό 곡λ³μ μΌλ‘ μ§μ νλ©΄ ν΄λμ€ λ΄λΆμμ κ·Έ νλΌλ―Έν° μ¬μ© λ°©λ²μ΄ μ νλλλ°, νμ μμ μ±μ μν΄μλ μμ°(read)μΌλ‘ κ³ μ λκ³ μλΉ(write)κ° λΆκ°λ₯νλ€λ μ μ΄λ€.
μμ°/ μλΉ λμμ΄λ€. inμμ Tνμ κ°μ μλΉνκ³ , outμμ Tνμ κ°μ μμ°νλ€. λ°λΌμ 곡λ³μ μΌλ‘ μ μΈνλ €λ©΄ outμμΉμ μ‘΄μ¬νλ κ²½μ° μμ νλ€.
out ν€μλμ μλ―Έκ° μ΄μ νμ€ν΄μ‘λ€.
- 곡λ³μ±
- Tλ₯Ό μμμμΉμμλ§ μ¬μ©ν μ μκ² μ¬μ©μ ν
μμ±μ νλΌλ―Έν°λ in/out μ΄λμͺ½μλ μνμ§μλλ€. κ·Έ μ΄μ λ μμ±μλ μΈμ€ν΄μ€λ₯Ό μμ±ν λ νΈμΆλμ§ κ·Έ μ΄ν νΈμΆν μ μλ λ©μλκ° μλκΈ° λλ¬Έμ΄λ€. λ€λ§ μμ±μ νλΌλ―Έν°λ₯Ό νλ‘νΌν°λ‘ λ§λ λ€λ©΄ 그건 in/outμ μνλ€.
λ λ³μ±κ·μΉμ ν΄λμ€ μΈλΆμμμ μμ μ±μ ν보νκΈ° μν¨μ΄λ―λ‘ public, protected, internal ν΄λμ€μλ§ μ μ©λκ³ ν΄λμ€ λ΄λΆμλ§ μ ν¨ν privateμλ μ μ©λμ§μλλ€.
λ°κ³΅λ³μ±(contravariance)λ 곡λ³μ±μ 180λ λ€μ§μ΄ λ κ²μ΄λ€.
곡λ³μ±μ΄ μμ°μ(read) κ΄μ μμ λμ¨κ²μ΄λΌλ©΄ λ°κ³΅λ³μ±μ μλΉμ(write)κ΄μ μ΄λ€. λ°λΌμ inν€μλμ μμΉκ° λ°κ³΅λ³μ±μ ν΅μ¬μ΄κ³ νμ μΈμμ νμνμ κ΄κ³κ° λ€μ§νμ μ λ€λ¦ μΈμλ‘ λ€μ΄κ°κ² λλ€.
μ§κΈκΉμ§ ν΄λμ€λ₯Ό μ μΈνλ©΄μ λ³μ±μ μ§μ νλ€. μ΄κ±Έ μ μΈμ§μ λ³μ±μ΄λΌκ³ νκ³ , νΉμ νμ νλΌλ―Έν°κ° λνλλ μ§μ μμ λ³μ±μ κ²°μ νλ κ±Έ μ¬μ©μ§μ λ³μ±μ΄λΌκ³ νλ€.
fun <T> copyData(src: MutableList<out T>)
νΈμΆ μ§μ μ outμ λΆμ¬μ Tνμ μ outμ μ¬μ©νλ λ©μλλ§ νΈμΆνλ€κ³ μ μΈν΄λ²λ¦° μμλ€. μ΄λ MutableListλ μ μ½μ κ°ν΄μ§ νμ μΌλ‘ λ°λλ©° μ΄κ±Έ νμ νλ‘μ μ μ΄λΌκ³ νλ€.
μ€ν νλ‘μ μ
μ λ€λ¦ νμ μΈμ μ λ³΄κ° μμμ νννκΈ° μν΄ μ€ν νλ‘μ μ μ μ¬μ©νκ³ , μμ νμ μ΄ μλ €μ§μ§ μμ 리μ€νΈλ List<*> λΌλ ꡬ문μΌλ‘ ννν μ μλ€κ³ μμ μμλ‘ λ΄€λ€.
μ€μν λͺκ°μ§λ₯Ό μ§κ³ κ°λ©΄ *μ μ νν μλ―Έκ° μ΄λ€ μ ν΄μ§ νμ μ μμλ₯Ό λ΄μ§λ§ κ·Έ μμμ νμ μ μ νν λͺ¨λ₯Έλ€λ κ²μ΄μ§ MutableList<*> == MutableList<Any?>λ‘ λμΉν μ μλ κ² μλλΌλ μ μ΄λ€.
fun printFirst(list: List<*>) { // λͺ¨λ ꡬ체μ νμ
μ 리μ€νΈλ₯Ό μΈμλ‘ λ°μ μ μλ€.
if (list.isNotEmpty()) { // isNotEmpty()μμλ Tλ₯Ό μ¬μ©νμ§ μλλ€.
println(list.first()) // first()λ μ΄μ Any?λ₯Ό λ°ν.
}
}
νλ‘μ μ μ΄ λΆλ μ΄μ λ *κ° out Any?μ²λΌ λμνκΈ° λλ¬Έμ΄λ€. λ°λλ‘ inμΌλ μ€ννλ‘μ μ μ μ§μ νλ©΄ μλΉλμμ΄ μ΄λ€ TμΈμ§ μ μ μκΈ° λλ¬Έμ in NothingμΌλ‘ μλνλ€. λ νμ νλΌλ―Έν°λ₯Ό μκ·Έλμ²μμ μ ν μΈκΈνμ§ μκ±°λ λ°μ΄ν°λ₯Ό μ½κΈ°λ νμ§λ§ κ·Έ νμ μλ κ΄μ¬μ΄ μλ κ²½μ°μ κ°μ΄ νμ μΈμ μ λ³΄κ° μ€μνμ§ μμ λλ μ€ν νλ‘μ μ ꡬ문μ μ¬μ©ν μ μλ€.
'πποΈ > μ½νλ¦° μΈ μ‘μ π' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
Kotlin in action(5) (0) | 2023.10.10 |
---|---|
Kotlin in action(4) (0) | 2023.10.10 |
Kotlin in action(3) (0) | 2023.10.10 |
Kotlin in action(2) (0) | 2023.10.10 |
Kotlin in action(1) (0) | 2023.10.10 |