스마트 캐스트는 조건문 등을 통해 변수가 자동으로 변환되는 것을 말한다. if 문에서 Null check를 했다면 if문의 스코프 내부에서는 not null로 자동 변환되는걸 예시로 들 수 있다.
2.0 이전에는 if문 외부에서 is casting을 하면 기존에는 if문 스코프에서는 if condition에 대한 정보가 없어 smart-case가 실패해서 관련함수를 부를 수 없었다.
하지만 2.0부터는 if, when, while 외부에서 조건문에 사용할 변수를 선언해도 접근가능한 스코프에 맞는 타입으로 스마트 캐스팅을 해준다.
이런 변경점은 boolean condition을 변수로 빼내서 코드의 가독성과 재사용성을 높일 수 있다.
class Cat {
fun purr() {
println("Purr purr")
}
}
fun petAnimal(animal: Any) {
val isCat = animal is Cat
if (isCat) {
// 2.0 이전에는 해당 함수를 부를 수 없음
// 2.0 부터는 스마트 캐스팅을 해줌
animal.purr()
}
}
fun main() {
val kitty = Cat()
petAnimal(kitty)
// Purr purr
}
or operator(||)을 통해 오브젝트 타입 체크를 할 때 기존에는 Any 타입으로 항상 캐스팅되어서 슈퍼타입의 함수를 호출할 수 없었지만 2.0부터는 가장 가까운 공통 슈퍼타입으로 캐스팅된다.
interface Status {
fun signal() {}
}
interface Ok : Status
interface Postponed : Status
interface Declined : Status
fun signalCheck(signalStatus: Any) {
if (signalStatus is Postponed || signalStatus is Declined) {
// 2.0 이전에는 해당 함수를 호출하면 Unresolved reference error가 반겨준다.
// 2.0부터는 슈퍼타입인 Status로 스마트 캐스팅을 해주기에 호출가능
signalStatus.signal()
// 2.0 이전이라면 아래와 같이 한번 더 타입체크를 해줘야 정상적으로 signal()를 호출할 수 있다.
// check(signalStatus is Status)
// signalStatus.signal()
}
}
테스트 실패 메세지에 더 다양한 정보를 포함시켜 보여주는 플러그인으로 아직은 experimental 단계이다.
참고문서
String Skipping Mode는 컴포지션 발생 시 인풋이 달라졌다는 걸 두가지 방법으로 체크한다.
.equals())===)기존에는 @Immutable같은 어노테이션을 활용하거나 래핑클래스를 만들고 해당 클래스에 어노테이션을 추가, Immutable Collection을 사용하는 방법이 있었다.
java.time.LocalDate 처럼 코드를 수정할 수 없는 경우에는 래퍼를 만드는 방법말고는 없었는데 이제는 config 파일을 통해 해당 파일에서 지정한건 모두 stable로 판단될 수 있다.
composeCompiler에 root 단에 생성한 설정 파일을 지정해주면된다.
composeCompiler {
...
// Set path of the config file
stabilityConfigurationFile = rootProject.file("stability_config.conf")
}
해당 방법을 사용하면 도메인 단에 있는 클래스들도 설정이 가능하니 프레젠테이션과 도메인단의 매퍼를 제거할 수도 있다.
// stabilize all classes in model package
com.example.app.domain.model.*
strong skipping ahemdml 다른 이점으로는 unstable한 캡처임에도 모든 람다는 remember 된다. 예전에는 뷰모델의 함수를 넘기는 경우 컴포지션을 발생시킬 수도 있어 람다를 remember 했는데 이제는 안해도 된다. 컴포즈 컴파일러가 자동으로 remember 해준다.
위에서 설명한 stability configuration에 기존의 컬랙션들을 추가하면 컬랙션 또한 stable로 간주될텐데 그럼 Immutable Collection이 필요없는가 할 수 있지만 아니다.
경우에 따라서는 그냥 List보다 더 느려지는 경우가 있다.
List를 설정파일에 추가하면 리스트 내부의 모든 아이템에 대해서 equals콜이 이루어지게된다. 만약 lazyList 환경이라면 더 많은 횟수의 equals가 발생하게 된다.
따라서 적용하기전에 한번 Macrobenchmark를 돌려 확인해 보는게 좋다고 한다.