Kotlin CompareTo 문자열 비교 (feat.실무) | Andorid

Pudrioid·2024년 10월 1일
post-thumbnail

Intro.


오늘은 막 입사하여 코드 분석 중에 발생한 일을 다룰려고 한다.


신입 개발자로 정신없이 업무를 하던 중, 앱 버전 체크 코드를 발견했다.

val nowVersion = 1.1.1.split(".")
val updateVersion = 1.1.2.split(".")
val lastestVersion = 1.1.3.split(".")

for(i in 0..2){
	if(nowVersion[i] < updateVersion[i]){
    	println("업데이트 안하면 사용 못함 ㅋㅋ")
    }
	if(nowVersion[i] < lastestVersion[i]){
    	println("새 버전 나옴")
    }
}

대략 이런 모양이였는데
나에겐 이 코드가 비효율적으로 보였다..ㅜㅜ

하나하나 비교하는게 안좋게 보였던 것 같다.

어떻게 하면 더 쉽게 동작할 수 있을까 고민하던 중
문자열 크기 비교 방법을 찾았다.

val nowVersion = 1.1.1
val updateVersion = 1.1.2
val lastestVersion = 1.1.3

if(nowVersion < updateVersion){
	println("업데이트 안하면 사용 못함 ㅋㅋ")
}else if(nowVersion < lastestVersion){
	println("새 버전 나옴")
}

실제로 println("1.1.1" < "1.1.2") 출력 시 true가 나오는 것 처럼
훨씬 간단하고 직관적이라 도입해볼 수 있을 것 같아서 사수님께 도입하자고 말씀드릴 계획이였다.
그 전에 원리를 파악해보려고 검색을 해보았다.


그런데!!!!!!!!!

사실 이 방법은 매우매우 위험한 방법이였고, 도입했다면 난리가 났을 것 같다ㅠㅠ
(사용자 화면에 업데이트 문구가 마구마구 뜰뻔함..)


그 이유를 알아보자..!!



CompareTo


val nowVersion = 1.1.1
val updateVersion = 1.1.2
println(nowVersion < updateVersion) // true

val nowVersion = 1.1.100000
val updateVersion = 1.5.1
println(nowVersion < updateVersion) // true

다음 코드는 예상대로 동작한다.
짧게 테스트 했을 때, 잘 동작한다고 생각해서 대참사 날 뻔...

어떻게 문자열을 비교할까??


위치

비교 연산자(<, >)를 ctrl 누른 상태로 타고 들어가보자.
그럼 String.kt 에 다음과 같은 함수로 연결된 것을 확인할 수 있다.

또 이 함수의 인터페이스를 확인해보면 여기까지 도달 할 수 있다.

이 인터페이스를 어디선가 상속받고 구현한게 있을텐데,
잘 안나와서 찾지 못하였다ㅠㅠ
(구현체 위치 아시는분은 댓글 부탁드려용)



String.compareTo(String)

우리가 알고싶었던 함수의 기능은 다음과 같다.

String.compareTo(String)

두 문자열이 있을 때,
맨 앞부터 각 각 하나씩 Char 형으로 변환하여 ASCII 코드 값으로 비교하는 방식이다.
같다면 0을,
다르면 길이의 차이만큼 Int 값을 반환해준다.

위에서 사용했던 코드를 바꿔보면 다음과 같다.

val nowVersion = 1.1.1
val updateVersion = 1.1.2

//println(nowVersion < updateVersion) // true
println(nowVersion.compareTo(updateVersion)) // true

A.compareTo(B)를 사용하면 Int 값을 뱉고
비교 연산자를 사용할 경우 같고 다름만 판단하여 Boolean 값을 뱉는 것으로 보인다.



버전 비교 코드에 도입했다면?

val nowVersion = 1.1.1
val updateVersion = 1.1.2
println(nowVersion < updateVersion) // true

val nowVersion = 1.1.100000
val updateVersion = 1.5.1
println(nowVersion < updateVersion) // true

다음과 같은 코드는 잘 비교되지만,
string.compareTo(string)은 맨 앞부터 하나하나 Char 형으로 변환하여 ASCII 코드로 비교한다고 했다.

val nowVersion = 1.1.10
val updateVersion = 1.1.5
println(nowVersion < updateVersion) // false

분명 nowVersion 의 버전이 더 높으나
앞부터 하나 하나 비교할 경우 컴퓨터는 updateVersion 이 더 높다고 인식한다.

이걸 상용앱에 도입했다간 정말이지 아찔할뻔..ㅠㅠㅠㅠㅠ



느낀점

무엇이든 원리를 파악하고 사용하자!!

안그럼 짤린다!

profile
안녕하세요 자라는 새싹 안드로이드 개발자입니다.

0개의 댓글