티스토리 뷰

Mobile/Android

[Android/kotlin] Generics

out of coding 2017. 10. 24. 17:35

시작


Java와 동일하게 kotlin에서도 Generics를 사용할수 있다.
오늘은 그 사용 방법에 대해서 이야기를 하여 보자.


제네릭스?


제네릭스를 사용하는 이유는 타입의 안정성을 제공하고 타입 체크와 형변환을 생략 가능하도록하여 코드가 간결해질수 있다.
내가 사용하려는 형을 넣어주므로써 다른 타입은 사용할수 없는것이다.
예를 들어 list변수가 ArrayList<String> 일 경우에는 Int형식은 넣어서 사용할 수 없도록 하는 것이다.


사용


다음과 같이 interface를 이용하여서 하나의 타입을 받아서 처리할수 있도록 구현이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface Generic<T> {
    fun getItem(): T
    fun setItem(item: T)
}
 
class GenericClass: Generic<Int> {
 
    var data: Int = 0
 
    override fun getItem(): Int {
        return data
    }
 
    override fun setItem(item: Int) {
        data = item
    }
}
 
class Test {
    fun test() {
        var generic = GenericClass()
        generic.setItem(1)
        generic.getItem()
    }
}
cs


와일드카드


자바 이야기를 하면 아마도 쉽게 이해가 갈것 같아서 자바를 적어봄.
만약 Generics Type이 다음과 같을 경우에는 동작이 이렇게만 된다.

T : Read / Write 모두 가능
? extends T : Read만 가능한 서비스타입 와일드 카드
? super T : Write만 가능한 슈퍼 타입 와일드 카드

그렇다면 kotlin의 이야기다.

T : Read / Write 모두 가능
out T : Read만 가능.
in T : Write만 가능


예제


파라메터에 out을 넣어주고 내부에서 이것을 조작하려고 할 경우에 정상적으로 동작하지 않습니다.
* add할 경우에 에러가 발생.

1
2
3
4
5
class Test {
    fun test(items: ArrayList<out String>) {
        items.add("test")
    }
}
cs

다음과 같이 in을 사용하여야 합니다.

1
2
3
4
5
class Test {
    fun test(items: ArrayList<in String>) {
        items.add("Test")
    }
}
cs

당연한 이야기 이겠지만 out이라고 되어 있어서 read는 가능하지만 write는 되지 않는것입니다.


function의 경우에 Generics Type을 받아서, 그대로 List를 리턴 받는 형식을 만들어봅니다.

1
2
3
4
5
6
7
8
9
class Test {
    fun <T> createArrayList(): List<T> {
        return ArrayList<T>()
    }
 
    fun test() {
        val array = createArrayList<Int>()
    }
}
cs

예제에서는 ArrayList<T>라고 표현하였지만 ArrayList라고 하면 알아서 추론하여 리턴을 하게 됩니다...


우리가 만드는 class나 기타 만들어진 generics에서는 다음과 같이 추론도 가능합니다.

1
2
3
4
5
6
7
8
9
10
class Foo<out T>(val value: T)
 
class Test {
    val foo1 = Foo<String>("foo1")
    val foo2 = Foo("foo2")
 
    fun test() {
        foo2.value
    }
}
cs

아래의 형식처럼 String형식을 안 넣어주어도 됩니다.


Star Projections


쉽게 말하면 java의 Object로 Generics type으로 선언하여 주는것과 동일하다.
어떠한 타입도 그냥 넣을수 있게 만드는것...

1
2
3
4
5
6
7
8
9
10
11
12
13
class Test {
 
    private fun print(array: List<*>) {
        array.forEach { 
            println("item : $it")
        }
    }
    
    fun test() {
        print(array = mutableListOf("a""b""c"))
        print(array = mutableListOf(123))
    }
}
cs


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함