π νλ©΄μ λκ² νμλ©΄ μ€λ₯Έμͺ½μμ λͺ©μ°¨λ₯Ό νμΈνμ€ μ μμ΅λλ€. :)
μ λ€λ¦ νμ νλΌλ―Έν°
μ λ€λ¦ νμ νλΌλ―Έν°λ₯Ό μ¬μ©νμ¬ μ λ€λ¦ ν¨μ, νλ‘νΌν°, ν΄λμ€λ₯Ό μ μΈνλ λ°©μμ μλ°μ λΉμ·νλ€.
μ λ€λ¦μ€λ₯Ό μ¬μ©νμ¬ νμ νλΌλ―Έν°λ₯Ό λ°λ νμ μ μ μν μ μκ³ , νμ μΈμλ‘ μΉννμ¬ μΈμ€ν΄μ€λ₯Ό λ§λ€ μ μλ€. νμ μΈμ(type argument)λ νλ‘κ·Έλλ¨Έκ° μ§μ νμ μΈμλ₯Ό μ μνκ±°λ μ»΄νμΌ κ³Όμ μμ νμ μΆλ‘ μ μν΄ νμ μΈμκ° μΆλ‘ λ μ μμ΄μΌνλ€.
List<String> // νμ νλΌλ―Έν°λ‘ Stringμ λ°κ³ μλ 리μ€νΈ
μ λ€λ¦ ν¨μμ νλ‘νΌν°
리μ€νΈλ₯Ό λ€λ£¨λ ν¨μλ₯Ό μμ±ν λ, λͺ¨λ 리μ€νΈλ₯Ό λ€λ£° μ μλ ν¨μλ₯Ό λ§λ€κ³ μΆμ λ μ λ€λ¦ ν¨μλ₯Ό μμ±νλ€.
- μ λ€λ¦ νμ₯ νλ‘νΌν°λ λ§μ°¬κ°μ§λ‘ νμ λ§λΌλ―Έν°λ₯Ό μ μΈνμ¬ μ¬μ© κ°λ₯νλ€.
val <T> List<T>.penultimate: T
get() = this[size-2]
fun main() {
println(listOf(1, 2, 3, 4).penultimate)
}
μ λ€λ¦ ν΄λμ€ μ μΈ
ν΄λμ€, μΈν°νμ΄μ€μ νμ νλΌλ―Έν°λ₯Ό μ μν΄μ λ³Έλ¬Έ μμμ μΌλ° νμ μ²λΌ μ¬μ© κ°λ₯νλ€.
interface List<T> {
operator fun get(index: Int): T
}
νμ νλΌλ―Έν° μ μ½ (type parameter constraint)
Type parameter μ μ½μ΄λ, ν΄λμ€λ ν¨μμ μ¬μ©ν μ μλ νμ
μΈμλ₯Ό μ ννλ κΈ°λ₯μ΄λ€. νμ
νλΌλ―Έν° μ΄λ¦ λ€μ :
λ₯Ό νμνκ³ λ€μ μν νμ
μ λͺ
μν΄μ μ νν μ μλ€.
fun <T: Number> List<T>.sum(): T
- λκ°μ§ μ΄μμ μ μ½μ λ¬μΌνλ κ²½μ°:
fun <T> ensureTrailingPeriod(seq: T)
where T: CharSequence, T: Appendable { // νμ
νλΌλ―Έν° μ μ½ λͺ©λ‘
if (!seq.endsWith('.')) { // CharSequence μΈν°νμ΄μ€μ νμ₯ ν¨μ νΈμΆ
seq.append('.') // Appendable μΈν°νμ΄μ€μ λ©μλ νΈμΆ
}
}
νμ νλΌλ―Έν°λ₯Ό λμ΄ λ μ μλ νμ μΌλ‘ νμ
- μνμ΄ μλ νμ
μ
Any?
μ λ§μ°¬κ°μ§λ‘ λμ νμ©νλ€. <T: Any>
λ‘ νμ μ νμ ν΄μ λμ΄ λ μ μλ νμ μ 보μ₯ν μ μλ€.
μ€ν μ μ λλ¦μ€μ λμ: μκ±°λ νμ νλΌλ―Έν°μ μ€μ²΄νλ νμ νλΌλ―Έν°
ν¨μλ₯Ό inline
μΌλ‘ μ μΈν΄μ μ λλ¦μ€ μ¬μ© μ νμ
μκ±°λ₯Ό λ§μ μ μλ€ (μ€μ²΄νν νμ
νλΌλ―Έν°).
μ€ν μμ μ μ λ€λ¦: νμ κ²μ¬μ μΊμ€νΈ
μ λ€λ¦ ν΄λμ€ μΈμ€ν΄μ€κ° μΈμ€ν΄μ€λ₯Ό μμ±ν λ μ°μΈ νμ μΈμμ λν μ 보λ₯Ό μ μ§νμ§ μλλ€.
- μ€ν μμ μμ
List<String>
κ³ΌList<Int>
λλ€ Listλ‘λ§ λ³΄μ.
νμ κ²μ¬
- μ»΄νμΌ μμ μ νμ
μ 보λ₯Ό μ 곡νλ©΄
is
κ²μ¬κ° κ°λ₯νλ€. (μλ κ²½μ°μ μ»΄νμΌ μλ¬)
fun printSum(c: Collection<Int>) { // νμ
μ 보λ₯Ό μ 곡ν¨.
if (c is List<Int>) {
println(c.sum())
}
}
fun main() {
val typeCasting = TypeCasting()
printSum(listOf(1,2,3))
}
νμ μΊμ€νΈ
- κΈ°μ ν΄λμ€λ κ°μ§λ§ νμ μΈμκ° λ€λ₯Έ νμ μΌλ‘ μΊμ€ν ν΄λ μλ¬κ° λμ§ μμμ μ£Όμν΄μΌνλ€.
fun printSum(c: Collection<*>) {
val intList = c as? List<Int>
?: throw IllegalArgumentException("List is expected")
/// BREAKPOINT : intList[0] = "a", intList[1] = "b", intList[2] = "c"
println(intList.sum()) // ClassCastException λ°μ
}
fun main() {
printSum(listOf(1,2,3))
printSum(listOf("a", "b", "c")) //List<String>
}
μ€μ²΄νν νμ νλΌλ―Έν°λ₯Ό μ¬μ©ν ν¨μ μ μΈ
μΈλΌμΈ ν¨μμ νμ νλΌλ―Έν°λ μ€μ²΄νλμ΄μ μ€ν μμ μ μΈλΌμΈ ν¨μμ νμ μΈμλ₯Ό μ μ μλ€.
- μΈλΌμΈ ν¨μμ νμ
νλΌλ―Έν°λ₯Ό
reified
λ‘ μ§μ νλ©΄ μ€ν μμ μ νμ κ²μ¬ κ°λ₯νλ€.- μ»΄νμΌ μ ν¨μκ° νΈμΆλλ μ½λ μ§μ μ μΈλΌμΈ ν¨μμ λ³Έλ¬Έμ ꡬνν λ°μ΄νΈμ½λκ° λ€μ΄κ°κ² λ¨
- = νμ μΈμλ‘ μ°μΈ ꡬ체μ μΈ ν΄λμ€λ₯Ό μ°Έμ‘°νλ λ°μ΄νΈ μ½λλ₯Ό μμ±
fun main() {
val items =listOf("one", 2, "three")
println(items.filterIsInstance<String>())
}
μ€μ²΄νν νμ νλΌλ―Έν° μ μ½
κ°λ μΌλ‘ μΈν΄ μκΈ°λ μ μ½ λ° μ½νλ¦°μ΄ μ€μ²΄νλ₯Ό ꡬννλ λ°©μμ μν΄ μκΈ°λ μ μ½
- νμ νλΌλ―Έν° ν΄λμ€μ μΈμ€ν΄μ€ μμ±νκΈ°
- νμ νλΌλ―Έν° ν΄λμ€μ λλ° κ°μ²΄ λ©μλ νΈμΆνκΈ°
- μ€μ²΄νν νμ νλΌλ―Έν°λ₯Ό μꡬνλ ν¨μλ₯Ό νΈμΆνλ©΄μ μ€μ²΄ννμ§ μμ νμ νλΌλ―Έν°λ‘ λ°μ νμ μ νμ μΈμλ‘ λκΈ°κΈ°
- ν΄λμ€, νλ‘νΌν°, μΈλΌμΈ ν¨μκ° μλ ν¨μμ νμ νλΌλ―Έν°λ₯Ό refiedλ‘ μ§μ νκΈ°
μ€μ²΄νν νμ νλΌλ―Έν°λ₯Ό μ¬μ©ν μ μλ κ²½μ°
- νμ κ²μ¬μ μΊμ€ν (is, !is, as, as?)
- 10μ₯μμ μ€λͺ ν μ½νλ¦° 리νλ μ API(::class)
- μ½νλ¦° νμ μ λμνλ java.lang.Classλ₯Ό μ»κΈ°(::class.java)
- λ€λ₯Έ ν¨μλ₯Ό νΈμΆν λ νμ μΈμλ‘ μ¬μ©
λ³μ±: μ λ€λ¦κ³Ό νμ νμ
λ³μ±μ νμ μ΄ κ°κ³ νμ μΈμκ° λ€λ₯Έ μ¬λ¬ νμ μ κ΄κ³λ₯Ό μ€λͺ νλ€. μνν μ¬μ§κ° μλ λ©μλλ₯Ό νΈμΆν μ μκ² λ§λ€μ΄μ ν΄λμ€ μΈμ€ν΄μ€λ₯Ό μλͺ» μ¬μ©νλ μΌμ λ°©μ§ν μ μλ€.
λ³μ±μ΄ μλ μ΄μ : μΈμλ₯Ό ν¨μμ λκΈ°κΈ°
μ μ ν μΈν°νμ΄μ€λ₯Ό μ νν΄μΌ μμ νμ§ λͺ»ν ν¨μ νΈμΆμ λ§μ μ μλ€. μλ₯Ό λ€μ΄, μ½κΈ° μ μ©μ List<Any>
vs. λ°μ΄ν° λ³κ²½μ΄ κ°λ₯ν MutableList<Any>
κ° μλ€κ³ νλ€λ©΄,
- μ½κΈ° μ μ©μΈ κ²½μ° κ΅¬μ²΄μ μΈ νμ μ μμλ₯Ό κ°λ 리μ€νΈλ₯Ό ν¨μμ λκΈΈ μ μλ€.
- MutableList<Any> νλΌλ―Έν°λ₯Ό λ°λ ν¨μμ MutableList<String>μ λκΈ°λ κ²½μ° λ¦¬μ€νΈμ μμκ° μΆκ°λκ±°λ λ³κ²½λλ©΄ νμ λΆμΌμΉκ° μκΈΈ μ μμ.
fun main() {
val strings =mutableListOf("abc", "def")
// addAnswer(strings)
// println(strings.maxBy { it.length })
}
fun addAnswer(list: MutableList<Any>) {
list.add(42)
}
ν΄λμ€, νμ , νμ νμ
ν΄λμ€μ νμ
νμ κ³Ό ν΄λμ€λΌλ μ©μ΄κ° νΌμ©λμμ§λ§, κ°μ§ μλ€..!
ν΄λμ€ μ΄λ¦μΌλ‘ νμ μ μΈ μ μκ³ , nullμ΄ λ μλ μλ νμ /μλ νμ λ μ΄μμ νμ μ ꡬμ±ν μ μλ€. μ λ€λ¦ ν΄λμ€λ λ§μ νμ μ λ§λ€μ΄λΌ μ μλ€.
- List<T> : ν΄λμ€
- List<String>, List<Int>, List<String?> : νμ
νμ νμ κ³Ό μμ νμ
νμ Aμ ← νμ Bμ κ°μ λ£μ΄λ λλ κ²½μ°:
- “νμ Bλ νμ Aμ νμ νμ μ΄λ€.”
- “νμ Aλ νμ Bμ μμ νμ μ΄λ€.”
- μ»΄νμΌλ¬λ λ³μ λμ
μ΄λ ν¨μ μΈμ μ λ¬ μ νμ νμ
κ²μ¬λ₯Ό λ§€λ² μνν¨.
- νμ νμ μΈ κ²½μ°μλ§ λ³μμ κ° λμ μ νμ©
- λμ νμ©νλ ν΄λμ€κ° μλ ν΄λμ€λ³΄λ€ μμ νμ μ.
- Mutable<Any> ← Mutable<String> μμ-νμ νμ κ΄κ³κ° μλ.(μ΄μ μμ μ°Έμ‘°)
곡λ³μ±: νμ νμ κ΄κ³λ₯Ό μ μ§
- 곡λ³μ (covariant): Aκ° Bμ νμ νμ
μ΄λ©΄ List<A>κ° List<B>μ νμ νμ
μΈ κ²½μ°
- νν λ°©μ:
<out T>
- νμ νλΌλ―Έν° μμ outμ λΆμ. - ↔ 무곡λ³(invariant): μΈμ€ν΄μ€ νμ κ° νμ νμ κ΄κ³κ° μ±λ¦½νμ§ μμ.
- νν λ°©μ:
out
κ³Όin
- ν΄λμ€ λ©€λ²λ₯Ό μ μΈν λ νμ νλΌλ―Έν°λ₯Ό μ¬μ©ν μ μλ μ§μ μ λͺ¨λ μΈ(in)κ³Ό μμ(out)μΌλ‘ λλ¨.:
- out: Tνμ
μ κ°μ “μμ°”
- νμ μμ μ± λ³΄μ₯μ μν΄ κ³΅λ³μ νλΌλ―Έν°λ νμ out μμΉμ μμ΄μΌ ν¨.
- in: Tνμ μ κ°μ “μλΉ”
- out+in : 무λ³μ±
λ°κ³΅λ³μ±: λ€μ§ν νμ νμ κ΄κ³
- λ°κ³΅λ³μ±(contravariance): Aκ° Bμ νμ νμ μ΄λ©΄ List<B>κ° List<A>μ νμ νμ μΈ κ²½μ°
곡λ³μ± μ§μ : μ μΈ μ§μ λ³μ± λλ μ¬μ© μ§μ λ³μ±
μ λ€λ¦ ν΄λμ€μ 곡λ³μ±μ μ 체μ μΌλ‘ μ§μ νκ±°λ ꡬ체μ μΈ μ¬μ© μμΉμμ μ§μ ν μ μλ€.
μ μΈ μ§μ λ³μ±
- ν΄λμ€λ₯Ό μ μΈνλ©΄μ λ³μ±μ μ§μ
- in/out μ§μ
- μμ ) Box ν΄λμ€ μ μμ μ€μ ν¨: T νμ μ out μμΉμμλ§ μ¬μ©ν μ μλλ‘ μ ν.
class Box<out T>(val data: T)
- val box: Box<Number> = Box(10) : Box κ°μ²΄λ Numberμ νμ νμ μΈ Int, Double νμ λ§ κ°μ§ μ μμ.
μ¬μ© μ§μ λ³μ±
- νμ νλΌλ―Έν°κ° μλ νμ μ μ¬μ©ν λλ§λ€ μ΄λ€ νμ μΌλ‘ λμΉν μ μλμ§ λͺ μνλ λ°©λ²(ν΄λΉ νμ νλΌλ―Έν° or νμ νμ μΌλ‘ λͺ μ)
- 곡λ³μ μ΄κ±°λ λ°κ³΅λ³μ μΈμ§ μ μΈν μ μλ κ²½μ° λ³μ±μ μ νλ λ°©λ²
- μμ μ€λͺ
- Box ν΄λμ€λ 무λ³μ±μ΄μ§λ§ printObj ν¨μμμ(=Box<> μ¬μ© μ§μ μμ) κ°λ³μ±μ μ νκ³ μ ν λ μ¬μ© μ§μ λ³μ±μΌλ‘ λ³μ±μ μ ν μ μμ.
- Box : 곡λ³μ±. μΈν°λ₯Ό ν΅ν΄ κ°μ μ€μ νλ κ²μ΄ μ νλ¨.
- Box ν΄λμ€λ 무λ³μ±μ΄μ§λ§ printObj ν¨μμμ(=Box<> μ¬μ© μ§μ μμ) κ°λ³μ±μ μ νκ³ μ ν λ μ¬μ© μ§μ λ³μ±μΌλ‘ λ³μ±μ μ ν μ μμ.
class Box<T>(var item: T) // 무λ³μ±
fun <T> printObj(box: Box<out Animal>) {
val obj: Animal = box.item // outμ΄λ―λ‘ getterκ° λμ
// box.item = Animal() <- outμ΄λ―λ‘ setterλ λμνμ§ μμ.
println(obj)
}
μ€ν νλ‘μ μ : νμ μΈμ λμ * μ¬μ©
μ λ€λ¦ νμ
μΈμ μ λ³΄κ° μμμ(μλ €μ§μ§ μμμ) ννν λ μ€ν νλ‘μ μ
(*
)μ μ¬μ©νλ€.
MutableList<*>
μMutableList<Any?>
- any? : κΈ°μ νμ μ λͺ¨λ νμ μ μμλ₯Ό λ΄μ μ μλ€λ μλ―Έ
- * : μμμ νμ μ λͺ¨λ₯Ό λΏ μ ν΄μ§ ꡬ체μ μΈ νμ μ μμλ§μ κ°μ§κ³ μμ.
- νμ μΈμ μ λ³΄κ° μ€μνμ§ μμ λ μ€ν νλ‘μ μ ꡬ문 μ¬μ©