분류 전체보기
[Kotlin] 제네릭 : 변성(variance), 타입 프로젝션(type projection)
[Kotlin] 제네릭 : 변성(variance), 타입 프로젝션(type projection)
2017.12.08``kt List``는 클래스(기저 클래스)이고, ``kt List``는 타입이다. 타입 ``kt A``의 값이 필요한 모든 장소에 타입 ``kt B``의 값을 넣어도 아무 문제가 없다면 ``kt B``는 ``kt A``의 하위 타입(subtype)이다. 하위 클래스와 하위 타입은 미묘한 차이가 있다. ``kt A?``와 ``kt A``는 같은 클래스에 속하지만, ``kt A``는 ``kt A?``의 하위 타입이고 그 역은 성립하지 않는다 무공변성, 불변성(invariance) 제네릭 타입을 인스턴스화할 때 서로 다른 타입 인자가 들어가는 경우 인스턴스 타입 사이의 하위 타입 관계가 성립하지 않으면 그 제네릭 타입을 무공변이라 한다. e.g., ``kt MutableList``에서 ``kt T``가 서로..
[Kotlin] 제네릭 : 타입 파라미터 소거(erasure), inline 실체화(reified)
[Kotlin] 제네릭 : 타입 파라미터 소거(erasure), inline 실체화(reified)
2017.12.08타입 파라미터 소거 [Kotlin] as와 타입 캐스팅. 런타임 에러. 타입 파라미터 소거(erasure) 런타임 타입 검사 : inline + reified (실체화한 타입 파라미터) ```kt inline fun isA(value: Any) = value is T >>> isA("a") true ``` 이게 가능한 이유는 인라인 함수는 함수 바디 코드가 함수 호출부에 삽입되기 때문에, 타입 인자가 아니라 구체적인 타입을 사용할 수 있기 때문이다. 자바에서는 ``kt reified``를 사용하는 ``kt inline`` 함수를 호출할 수 없다. 자바에서는 코틀린 인라인 함수를 다른 보통 함수처럼 호출해버려서 타입 정보가 사라지기 때문이다. inline reified 함수 내에서 위 예제처럼 실제 타입간..
[Kotlin] 컬렉션과 배열
[Kotlin] 컬렉션과 배열
2017.12.07filterNotNull() : 널이 아닌 값만 추리고 싶은 경우```kt>>> val l = listOf(1, 2, null, 4, 5)>>> println(l.filterNotNull())[1, 2, 4, 5]```Note ) 걸러내고 난 결과 컬렉션의 타입은 ``kt null``이 제거되었으므로 ``kt List`` 타입이 된다. filterIsInstance() : 특정 타입만 추리고 싶은 경우```kt>>> val li = listOf(1, "b", 3)>>> li.filterIsInstance()[1, 3]``` toTypedArray() : 배열을 넘겨야 하는데 데이터가 컬렉션에 들어있다면 배열로 변환```kt>>> val strings = listOf("a", "b", "c")>>> pri..
[Kotlin] 타입 시스템 (Any, Unit, Nothing)
[Kotlin] 타입 시스템 (Any, Unit, Nothing)
2017.12.06코틀린에서는 원시 타입과 참조 타입(래퍼 타입, 포인터 변수)을 별도 타입으로 따로 구분하지 않는다. 예를 들어 java의 int와 Integer 같이 구분하지 않고, Int 하나로 쓴다. 널이 될 수 없는 타입은 컴파일 시 알아서 원시 타입으로 표현할 수 있는건 원시 타입으로 표현해주고, 메소드를 호출하는 등 래퍼 타입이어야 하는 경우 래퍼 타입으로 변환해준다. 널이 될 수 있는 타입의 경우 ``kt null``은 원시 타입에는 들어갈 수 없고, 참조 타입에만 들어갈 수 있으므로 무조건 래퍼 타입으로 컴파일된다. 타입 상한 : 제네릭의 타입 파라미터 T는 T?가 아니어도 널이 될 수 있는 타입이다. 제네릭 클래스(T)의 경우 T에 원시 타입을 지정하더라도 내부적으로는 항상 그에 대한 박스 타입을 사용한..
[Kotlin] Nullability 관련 연산자
[Kotlin] Nullability 관련 연산자
2017.12.06최근 null에 대한 접근 방법은 런타임에 발생하는 NPE를, 컴파일 타임으로 옮기는 것이다. 널이 될 수 있음과 없음에 대한 모든 검사는 컴파일 타임에 수행되기 때문에, 실행 시점에는 널이 될 수 있는 타입과 널이 될 수 없는 타입의 객체가 같아진다. 단, ``kt @NotNull`` 애너테이션이나 ``java Intrinsics.checkExpressionValueIsNotNull()`` ``java Intrinsics.checkParameterIsNotNull()``같은 체크가 추가된다. 런타임에 ``kt null``을 가져와 non-null type에 집어 넣거나, ``kt !!``를 잘못 사용하는 경우 프로그램 실행 도중 다음 예외가 발생한다. ``java java.lang.IllegalStat..
[Kotlin] 수신 객체 지정 람다 : with / apply / let / run / takeif / also
[Kotlin] 수신 객체 지정 람다 : with / apply / let / run / takeif / also
2017.12.05수신 객체 지정 람다 with : prefix없이 접근하고 싶을 때 ``kt with``는 원래 파라미터가 2개인 함수다. 그러나 두 번째 인자인 람다를 밖으로 빼서 원래 언어가 지원하는 구문인 것 처럼 사용할 수 있다. 보기 깔끔해진다. ``kt with``의 람다 내에서는 전달된 객체에 prefix없이 접근할 수 있다. ```kt fun alphabet(): String { val stringBuilder = StringBuilder() return with(stringBuilder) { for (letter in 'A'..'Z') { this.append(letter) append("!") // this 생략 가능 } this@OuterClass.somFunc() // 바깥쪽 클래스 멤버 접근 th..
[Kotlin] 함수형 인터페이스(SAM)에 람다 사용하기
[Kotlin] 함수형 인터페이스(SAM)에 람다 사용하기
2017.12.05주로 리스너 계열이 SAM으로 되어 있기 때문에, 리스너에 많이 사용한다.자바 8 이전에는 무명 객체를 사용했다.```javabutton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { . . . }});``` 코틀린(또는 자바8)에서는 SAM에 람다를 사용할 수 있다.```ktbutton.setOnClickLIstener({ v -> . . . })```이런 코드가 동작하는 이유는 단일 추상 메소드만 가지고 있기 때문에 람다가 어느 메소드를 대체해야 할지를 찾을 수 있기 때문이다.Note ) 코틀린 함수를 호출할 때는 람다를 넘겨도 코틀린 컴파일러가 람다를 무명 클래스 객체로 변환하지 않는다. 코틀린에는..
[Kotlin] stream API / 시퀀스(Sequence)
[Kotlin] stream API / 시퀀스(Sequence)
2017.12.04기본 filter, map 등은 인라인 함수로 정의되어 있어 알아서 인라이닝되므로 성능 신경쓰지말고 그냥 사용하면 된다. 연쇄해서 사용하는 경우 연산의 순서가 성능에 영향을 줄 수 있기 때문에 고려해야 한다. 보통 ``kt filter()``를 먼저 적용해 추리는게 도움이 되고, 메서드 체이닝 시 앞쪽에서 부터 적용되기 때문에 ``kt filter()``를 먼저 써주는게 좋다. ...고 하는데, 지연평가 기본적으로는 안되는게 맞다. collection에서 그냥 map, filter 사용 시 모든 원소에 대해 적용하고 다음으로 넘기는 방식. asSequence() 로 시퀀스 변경 후 map, filter 사용 시 lazy evaluation 됨. lazy eval && take, takeLast가 지원되는..
[Kotlin] 람다(lambda), 변수 포획과 클로저, 멤버 참조
[Kotlin] 람다(lambda), 변수 포획과 클로저, 멤버 참조
2017.12.04lambda ```kt { x: Int, y: Int -> x + y } ``` 코틀린 람다는 자바 람다와 달리 항상 중괄호 사이에 위치한다. 반면 메서드 참조는 중괄호 없이 써야 한다. 코틀린 람다 호출은 실행 시점에 아무런 부가 비용이 들지 않으며 기본 구성 요소와 비슷한 성능을 내기 때문에 적절하게 사용하는 것이 권장된다. 코틀린은 파이썬처럼 컬렉션의 최댓값을 찾거나 하는 기능이 기본적으로 구현되어 있기 때문에, 일단 한번 찾아보고 없으면 구현한다. 이런 컬렉션 라이브러리들이 보통 함수형으로 되어 있기 때문에 적용할 함수를 넘겨야 하는데, 이런 경우 람다를 사용하는 것이 좋다. ```kt >>> val people = listOf(Person("A", 23), Person("B", 25)) >>> ..
[Kotlin] 싱글턴 object(static) : 객체 선언, 동반 객체, 객체 식 / 익명, 무명
[Kotlin] 싱글턴 object(static) : 객체 선언, 동반 객체, 객체 식 / 익명, 무명
2017.12.03클래스를 정의하면서 동시에 인스턴스를 생성한다.!! 코틀린에는 ``java static``이 없고, 대신 이를 최상위 함수로 처리한다. 그러나 최상위 함수는 말 그대로 최상위에 존재하는 함수이기 때문에 어떤 클래스의 ``kt private``에는 당연히 접근할 수 없어 클래스 내부에 선언된 ``java static``이 클래스의 다른 멤버와 상호 작용하는 경우를 커버할 수 없다. 이렇게, ``java static``을 최상위 함수로 대체할 수 없을 때 ``kt object``를 고려한다. * ``kt object``를 사용하면 java로 변환시 ``java static``으로 컴파일된다. 1. 객체 선언(object declaration) : 싱글턴 객체 선언은 클래스 선언과 그 클래스에 속한 단일 인스..
고민이 길어질 때, 어느쪽 선택이 우세한지 감이 안올 때, 일단 짜라!
고민이 길어질 때, 어느쪽 선택이 우세한지 감이 안올 때, 일단 짜라!
2017.12.02이 글은 보호되어 있기 때문에 이것을 보려면 암호가 필요합니다.
[Kotlin] delegate 키워드 : by
[Kotlin] delegate 키워드 : by
2017.12.02클래스 delegation (컴포지션, composition) 상속을 허용하지 않는 클래스에 새로운 동작을 추가해야 할 때(Wrapping) 또는 메소드의 동작을 변경하고 싶을 때 위임을 사용하게 되는데 단점이 준비 코드가 너무 많이 필요하다는 점이다. 아래와 같이 `` innerList``를 Wrapping하게 되면 위와 같이 굳이 재정의하고 싶지 않은, 단순히 원래 클래스로 전달하고 싶은 코드도 모두 재정의해야 하기 때문에 상당히 난잡해진다. ```kt class DelegatingCollection0( private val innerList: ArrayList = arrayListOf() ) : Collection { override val size: Int get() = innerList.size..