[kotlin] 2. 코틀린 기초

References: Do it! 코틀린 프로그래밍


프로젝트, 모듈, 패키지, 파일

코틀린은 파일이 모여 패키지가 되고, 패키지가 모여 모듈이 된다.
파이썬에서는 모듈이 모여 패키지가 되더니 언어마다 다른건가 싶다.

코틀린 프로젝트 계층 구조

1
2
3
4
# 프로젝트  
## 모듈
### 패키지
#### 파일

패키지

같은 프로젝트 내에서 같은 클래스 이름을 쓰더라도 오류가 나지 않게 패키지 이름으로 분류한다.

  • 같은 프로젝트 내 Person 클래스 2개 -> 충돌 발생
  • 1번 패키지 내 Person 클래스 / 2번 패키지 내 Person 클래스 -> 문제없음

패키지 이름을 선언하지 않고 파일을 만들면 default 패키지 아래로 자동으로 들어간다.

- 보이지않는 default 패키지 아래에 존재하는 파일

패키지 명은 .으로 구분한다.

1
com.example.edu

기능이나 역할을 뒤에 추가로 넣어주면 좋다.

1
com.example.net.upload // 인터넷 업로드 기능을 하는 패키지명

다른 패키지 내 클래스 import 문법 및 클래스 객체로 만들기

1
2
3
package com.taeyeon93.study.freetest2

class Person(val name: String, val age:Int) // 클래스 선언
1
2
3
4
5
6
7
8
9
package com.taeyeon93.study.freetest         
import com.taeyeon93.study.freetest2.Person // 클래스 import

fun main() {
val user1 = Person("kildong", 30) // 클래스 객체로 만들기

println(user1.name)
println(user1.age)
}
1
2
3
실행결과
kildong
30

다른 패키지 내의 클래스명과 현재 패키지의 클래스명이 같아서 객체를 만들기 어려울 때 as 별명을 붙여 구분한다.

1
2
3
4
import com.example.edu.Person as User  
fun main() {
val user1 = User("kildong", 30)
}

변수/자료형

변수

변수는 val, var라는 키워드를 이용하여 선언한다.

  • val : 변할 수 없는 상수 선언시 사용 / C,C++ 등에서는 const
  • var : 일반적인 변수

코틀린은 자료형을 지정하지 않아도 자료형을 추론해서 알아서 자료형을 지정 할 수 있다.

1
2
val username = "Kildong"
// 코틀린이 자료형을 추론하여 username의 자료형을 String으로 결정

단, 자료형을 명시하지 않는 변수는 자료형을 추론할 수 있는 값을 지정해야 한다.

1
var username // 자료형이 지정되지 않아 선언불가

변수에 커서를 대고 Ctrl+Shift+P를 누르면 추론된 자료형을 볼 수 있다.

쌍따옴표 내부에서 변수를 사용할때는 $ 특수문자를 붙여야 한다.

1
2
3
4
5
6
fun main(){  
val number = 1234

println(number)
println("$number")
}

자료형

코틀린의 자료형은 참조형 자료형을 사용한다.

  • 기본형 자료형(Primitive Data Type) : int, long, float, double 등
  • 참조형 자료형(Reference Type) : String, Date 등

참조형으로 선언한 변수는 코틀린 컴파일러에서 다시 기본형 자료형으로 대체되기 때문에 굳이 기본형을 신경쓸 필요가 없다.

언더스코어를 사용하면 자릿값을 구분할 수 있다.

1
2
3
val number = 1_000_000
val cardNum = 1234_1234_1234_1234L
val hexVal = 0XAB_CD_EF_12

변수를 선언할때는 힙 영역에 실제 데이터를, 스택 영역에 주소값을 넣는다.

문자열 자료형은 동일한 문자열을 선언할 경우, 이미 힙 영역을 사용하고있는 문자열을 참조하는것이 효율적이므로
이전에 선언한 힙 영역의 실제 데이터를 참조하는 주소값을 생성한다.

1
2
3
4
5
6
7
8
9
10
fun main() {  
var str1: String = "Hello"
var str2 = "World"
var str3 = "Hello"
// 동일한 Hello 라는 값을 선언한 경우 str1이 갖고있는 값의 주소값을 스택에 넣는다.

println("str1 === str2: ${str1 === str2}")
println("str1 === str3: ${str1 === str3}")
// 주소값이 일치하므로 true
}
1
2
3
실행결과   
str1 === str2: false
str1 === str3: true

코틀린은 아예 변수에 null을 허용하지 않아 NullPointerException 오류가 발생하지 않는다.
그래서 코틀린에서 null을 허용하기위해서는 ? 기호를 이용해 선언해야 한다.

null을 허용한 변수를 사용하기위해선 세이프 콜과 non-null 단정 기호를 사용해야 한다.

  • 세이프 콜 : String? 과 같은 자료형은 변수 뒤에 ?. 을 붙여야 콜이 가능하다.
  • non-null 단정기호 : 세이프콜과 같은 역할이며 !!. 을 붙여서 콜을 하지만, null에 대한 검증을 거치지 않아 컴파일은 가능하나 빌드중에 NPE 에러를 낸다.
1
2
3
4
5
fun main() {  
var str1 : String? = "Hello Kotlin"
str1 = null
println("str1: ${str1?.length}") // 세이프콜
}
1
2
실행결과  
str1 : null
1
2
3
4
5
fun main() {  
var str1 : String? = "Hello Kotlin"
str1 = null
println("str1: ${str1!!.length}") // non-null 단정기호
}
1
2
3
4
실행결과
Exception in thread "main" kotlin.KotlinNullPointerException
at chap02.section3.Sec3Kt.main(sec3.kt:6)
at chap02.section3.Sec3Kt.main(sec3.kt)

엘비스 연산자를 이용하면 좀 더 안전하고 효율적으로 null을 허용한 변수를 사용할 수 있다.
변수에 들어있는 값이 null일경우 반환값을 특정한 값으로 대체할 수 있다.

  • 엘비스 연산자 : [?:] 왼쪽의 값이 null일 경우 오른쪽 값을 반환.
1
2
3
4
5
fun main() {  
var str1 : String? = "Hello Kotlin"
str1 = null
println("str1: $str1 length: ${str1?.length ?: -1}") // 엘비스 연산자 사용
}
1
2
실행결과  
str1: null length: -1

코틀린에서는 서로 다른 자료형의 변수를 비교하거나 연산할 수 없다.
서로 다른 변수를 같은 자료형으로 직접 만들어야 연산할 수 있다.
형변환은 toByte, toLong, toDouble 등을 통해서 변경한다.

어떤 변수가 정수일수도 있고 실수일 수도 있는 경우, 스마트 캐스트를 활용한다.
일반적으로 처음 선언한 자료형은 뒤에 다른 자료형을 대입할 수 없지만, 스마트캐스트를 이용하면 가능하다.
스마트캐스트는 Number, Any 등을 써서 다양하게 사용 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
fun main() {  
var test: Number = 12.2
println("$test")

test = 12
println("$test")

test = 120L
println("$test")

test += 12.0f
println("$test")
}
1
2
3
4
5
결과값  
12.2
12
120
132.0

$변수.javaClass 를 사용하면 변수의 자료형을 얻을 수 있다.

공유하기