티스토리 뷰
회사에서 자바+스프링으로 프로젝트를 진행하다 이번에 코틀린+스프링으로 진행하게되어 코틀린 문법을 정리하고자한다.
1. 변수
변수 선언 키워드
- val: 불변, 자바스크립트의 const, 자바의 final 키워드와 같다
- var: 가변, 자바스크립트의 let, 자바에서 흔히들 쓰는 변수들과 같다
변수 선언 방법
val myName:String = "dongjun"
"변수선언키워드 변수명:타입 = 값" 형식으로 변수를 선언한다.
val myName = "dongjun"
위와 같이 타입을 생략하고 변수 선언을 할 수 있다.
코틀린 컴파일러가 값을 보고 타입을 추론한다.
val myName //불가능
val myName:String //가능
myName = "dongjun"
단, 변수 선언과 할당을 동시에 하지 않을 경우에는 타입을 생략할 수 없다.
val myName = "dongjun"
println("name: " + myName)
println("name: $myName")
변수 사용시엔 자바처럼 사용도 가능하고 "$"를 붙혀 사용할 수도 있다.
2. 자료형
코틀린에선 기본적으로 참조형을 사용한다.
컴파일러가 내부적으로 기본형으로 바꿔서 최적화된 바이트코드로 만들어 준다고 한다. (컴파일시: 코틀린 -> 바이트 코드)
정수 자료형
- Long, Int, Short, Byte가 있다
- 변수 타입 추론 시, Int 범위 내에 있으면 Int로 하고 그 이상 Long 범위에 있으면 Long 으로 추론한다
- 정수 타입에선 Int가 기본형이다, Short 범위내에 정수라도 Short로 추론하지 않고 Int로 추론한다
- 값을 적을 때, underScore(_)를 추가할 수 있다. (언더스코어가 값에는 아무런 영향을 주지 않는다)
val myLong = 12_345_678_912_345_678 //Long 으로 추론 (언더스코어 사용 시, 자리수를 구분하는데 도움됨)
실수 자료형
- 기본적으로 double로 추론, 값에 F를 붙이면 Float 타입으로 추론한다
논리 자료형
- 값에 true, false를 사용하면 자동으로 Boolean으로 추론한다
val isCheck = true
문자 자료형
- '(single quote)' 으로 한 문자를 지정하면 Char로 추론한다
val charOne = 'c'
문자열 자료형
- 값에 문자를 배열하면 String 타입으로 추론한다
- 자바와 같이 힙에 StringPool을 공유한다
var a = "hello"
var b = "hello"
println(a == b) //true
- 문자열 내에 "(쌍따옴표), $(달러)를 쓰고 싶으면 \(백슬래시)를 앞에 붙여 사용하면 된다
val expression = "\"give\" me \$100"
- """ 통해 문자열을 표현할 수 있다
val formattedString = """
var a = 11
var b = "hello kotlin"
"""
3. 자료형 검사
코틀린 null(?)
코틀린은 null에 굉장히 민감하다. 지금까지 위에서 작성한 코드는 null을 허용하지 않는 방식이다.
null을 허용하고 싶으면 ?(물음표)를 타입 뒤에 붙혀 변수를 선언해야 한다.
//컴파일 에러
val str: String = "hello"
str = null
//타입 뒤에 ? 붙이면 null이 할당될 수 있는 변수라는 의미
var str2: String? = "hello"
str2 = null
non-null 단정 기호, 세이프 콜(safe call)
?(nullable)타입에선 !!.(non-null 단정기호), ?.(세이프 콜)만 쓸 수 있다.
var nullableString:String? = null
println("nullableString : $nullableString , length : ${nullableString.length}")
//nullableString을 참조하는 구문에서 아래와 같이 안내한다.
//Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
세이프 콜은 객체가 null 이면 해당 객체에 접근하지 않고 null을 리턴해주지만 non-null 단정 기호는 null이 아니라고 단정하고 접근하여 NPE를 발생시킨다. 따라서 세이프 콜을 주로 쓰자.
엘비스 연산자(?:)
엘비스 연산자는 값이 null이면, 뒤에 미리 지정해놓은 값을 리턴하는 연산자다.
var nullableString:String? = null
println("length : ${nullableString?.length ?: -1}") //-1이 출력됨
세이프 콜과 엘비스 연산자를 사용하면 우아하게 null 처리를 할 수 있다.
(자바에선 if 문이나 Optional을 사용해서 null을 처리해야했지만 코틀린으론 아주 간단하게 처리가능하다.)
(참고)
엘비스 프레슬리 헤어스타일과 비슷해 엘비스 연산자라고 한다ㅋㅋ
자료형 변환
자바에선 int 값을 double 변수에 할당하면 자동으로 형변환이 되지만, 코틀린 지원하지 않는다.
오히려 타입 미스매치 에러를 내면서 실수를 철저하게 방지한다.
val intValue:Int = 3
val doubleValue:Double = intValue.toDouble()
val result = 1L + 3 //Long으로 형변환 -> 표현범위가 더 큰 쪽으로 변환된다.
위와 같이 코틀린은 형변환 메서드를 제공한다.
*기본형과 참조형 타입 비교 원리
- 값 비교: ==
- 참조 주소 비교: ===
val one: Int = 128
val two: Int = 128
println(one == two) //true
println(one === two) //true
//참조 비교
val three: Int = 128
val four: Int? = 128
println(three == four) //true
println(three === four) //false
//Int형으로 선언된 three는 128값 자체가 스택에 저장되지만, Int?형으로 선언된 four는 128이 힙에 저장되어있고 그것의 주소로 저장한다.
val data1:Int = 128
val data2 = data1;
println(data1 == data2)//기본형으로 int로 변환되어 값이 동일하므로 true
val data3:Int? = data1 //128이라는 값을 힙에 할당하고 그것을 가리킨다.
val data4:Int? = data1 //128이라는 값을 힙에 할당하고 그것을 가리킨다.
val data5:Int? = data3
println(data3 == data4)//true 값만 비교했는데 두 개의 값은 128로 같다
println(data3 === data4)//false 각각 값은 128로 동일하지만 힙에 생긴 128은 각각생기기 때문에 다른 주소를 가리키므로 주소비교는 false
println(data3 === data5)//true data3는 128을 힙에 할당하고 그것을 가리키고 있다. data5는 data3를 가리키는데 data3가 힙의 128의 주소를 가리키고 있으므로
//복사되었을 때 같은 힙에 있는 128을 가리킨다.
null을 허용하지 않는 변수는 참조형을 사용하더라도 내부적으로 기본형으로 값을 갖게되서 스택 영역에 할당된다.
하지만 null을 허용하는 변수는 기본형으로 변환되는 참조형일지라도 힙 영역에 할당하고 그것을 가리키는 주소를 스택 영역에 할당한다.
128 ~ 127의 정수 값은 캐시에 저장되어 참조된다.
따라서 위의 예제에서 값을 10으로 바꾸면 10이라는 값자체가 캐시에 저장되고 모든 변수들은 다 그 캐시의 주소값을 저장한다.
그래서 10으로 테스트하면 data1 ~ data4까지 === 비교를 하면 다 true가 나오니 참고하자.
Number 타입
Number 타입으로 정의된 변수는 정수, 실수 둘다 들어갈 수 있다.
var sc:Number = 3.14
println(sc::class) //Double
sc = 3
println(sc::class) //Int
sc = 30L
println(sc::class) //Long
sc = 10.1F
println(sc::class) //Float
is 키워드
is를 통해 자료형 검사를 할 수 있다.
val cup = 3
if(cup is Int){
println("Int Type") //이것만 출력됨
}
if(cup !is Int){
println("Not a Int Type")
}
if(!(cup is Int)){
println("Not a Int Type")
}
as 키워드
as는 형변환이 가능하지 않으면 예외를 발생시킨다.
var y:Int = 3
val t:String = y as String //y가 null이 아니면 String으로 형변환되어 t에 할당된다. 만약 null이라면 형변환할 수 없으므로 exception 발생
//null이 발생할 가능성이 있다면 예외를 피하기 위해 아래와 같이 물음표를 붙여서 해결가능
val tt:String? = y as? String //y가 null이면 as키워드에 접근하지 않고 null 리턴. 그러면 tt는 null이 가능하니까 null 저장
4. 연산자
코틀린 연산자는 자바와 거의 똑같다.
+ - * / % (사칙연산, 나머지)
+= -= *= = %= (사칙연산 + 대입연산 축약형)
--a a-- ++a a++ (증감연산)
> >= < <= (비교연산)
== != === !==
&& || !
'개발 > Kotlin' 카테고리의 다른 글
[Kotlin] - 코틀린 기초 (컬렉션) (0) | 2022.09.03 |
---|---|
[Kotlin] - 코틀린 기초 (특별 클래스) (0) | 2022.08.20 |
[Kotlin] - 코틀린 기초 (제어문) (0) | 2022.08.16 |
[Kotlin] - 코틀린 기초 (Hello World, 함수, 클래스) (0) | 2022.08.15 |