코틀린에서의 프로젝트는 모듈(Module), 패키지(Package), 파일(File)로 구성되어 있다.
아래 구조는 하나의 예시이다.
HelloKotlin(프로젝트)
코틀린은 자바처럼 클래스 이름과 파일 이름이 동일해야 하고, public 클래스는 하나만 사용해야 하는 등의 규칙이 없다.
나는 Python을 주로 사용하다가 Java계열을 공부하면서 패키지를 만들어야 하는 이유가 궁금했다.
만약 2명의 프로그래머가 프로젝트를 진행하다 우연히 같은 이름의 파일(클래스)을 만들었다고 가정하면 당연히 오류가 발생하지만, 패키지가 다르면 오류가 발생하지 않는다.
예를 들면 HelloKotlin 모듈에서 default 패키지에 Person이라는 파일(클래스)을 만들고 com.example.edu 패키지에도 같인 이름의 Person 파일(클래스)을 만들어도 패키지가 다르기 때문에 프로그램이 정상적으로 실행된다.
default패키지와 com.example.edu패키지에서 Person이라는 파일(클래스)을 만드는 방법이 조금 다르다.
// com.example.edu 패키지에 Person 클래스 추가하기
package com.example.edu
class Person(val name: String, val age: Int)
// default 패키지에 Person 클래스 추가하기
class Person(val name: String, val age: Int)
코틀린에서 기본 패키지로 제공하고 있는 것들이 있다.
패키지 이름 | 설명 |
kotlin.* | Any, Int, Double 등 핵심 함수와 자료형 |
kotlin.text.* | 문자와 관련된 API |
kotlin.sequences.* | 컬렉션 자료형의 하나로 반복이 허용되는 개체를 열거 |
kotlin.ranges.* | if문이나 for문에서 사용할 범위 관련 요소 |
kotlin.io.* | 입출력 관련 API |
kotlin.collections.* | List, Set, Map 등의 컬렉션 |
kotlin.annotation.* | 애노테이션 관련 API |
위에 표를 제외한 기본 라이브러리들도 있는데, 대표적으로 math를 사용한 예시이다.
package chap02.section1
import kotlin.math.*
fun main() {
val intro : String = "안녕하세요!"
val num : Int = 20
println(PI)
println(abs(-12.6))
println("intro : $intro, num : $num")
}
val과 var의 차이
val : 변수를 선언하면 최초로 지정한 변수의 값으로 초기화하고 더 이상 바꿀 수 없는 읽기 전용 변수가 된다.
var : 변수를 선언하면 최초로 지정한 변수의 초깃값이 있더라고 값을 바꿀 수 있다.
코틀린의 변수 선언 방법은
val username : String = "Kildong" 이런식으로 선언한다.
val : 선언키워드
username : 변수 이름
String : 자료형
"Kildong" : 값
var username 처럼 자료형을 지정하지 않은 변수를 사용할 수 없다.
아래는 예제코드이다
package chap02.section2
fun main(){
val number = 10 // number 변수는 Int형으로 추론
var language = "Korean" // language 변수는 String으로 추론
val secondNumber : Int = 20 // secondNumber 변수는 자료형을 Int형으로 명시적으로 지정
language = "English" // var 키워드로 선언한 변수는 값을 다시 할당할 수 있음
println("number: $number")
println("language: $language")
println("secondNumber: $secondNumber")
}
int a = 77; // 기본형
Person person = new Person();
보통 우리는 기본형이 참조형보다 코드 수행시간이 더 빠른것으로 알고 있다.
하지만 코틀린은 겉으로는 참조형을 사용하는 것 같지만 컴파일 과정을 거치면 참조형이 기본형으로 바뀐다.
코틀린 컴파일러가 자동으로 최적화를 수행하는 것이다.
그러므로 기본형을 사용해야 할지 참조형을 사용해야 할지 고려할 필요 없이 참조형만 사용하면 된다.
표현식과 $ 기호 사용하여 문자열 출력하기
변수의 값이나 표현식을 문자열 안에 넣어 출력하려면 달러($) 기호와 함께 변수나 표현식을 사용하면 된다.
package chap02.section2
fun main() {
var a = 1
val str1 = "a = $a"
val str2 = "a = ${a+2}" // 문자열에 표현식 사용
println("str1: \"$str1\", str2: \"$str2\"")
}
자료형에 별명 붙이기
변수의 자료형이 복잡한 구조를 가지면 자료형에 별명을 붙일 수도 있다.
typealias라는 키워드를 사용한다.
typealias Username = String
val user: Username = "Kildong"
자료형 검사(null)
코틀린은 변수에 기본적으로 null을 허용하지 않는다.
아래 코드는 IntelliJ 에서의 예시이다.
null을 사용하기 위해서는 자료형 뒤에 물음표(?) 기호를 사용해야한다.
그렇다면 null이 할당된 상태에서 문자열의 길이를 어떻게 구할까?
.length 키워드를 사용해야하는데, 빨간 밑줄이 뜨는것을 확인할 수 있다.
이런 경우에는 변수명 뒤에 물음표 기호를 사용하면 된다.
실행한경우, 둘다 null이 출력되는것을 확인할 수 있다.
물음표 기호를 붙이는 것을 세이프 콜이라고 한다.
조건문을 활용해서 length값을 지정하는것도 안전한 방법인 것 같다.
null을 허용한 변수는 같은 값을 저장해도 이중 등호와 삼중 등호를 사용한 결과값이 다르다.
val a: Int = 128
val b: Int = 128
println(a == b) // true
println(a === b) // true
val a: Int = 128
val b: Int? = 128
println(a == b) // true
println(a === b) // false
이유는 Int 형으로 선언된것은 우리가 스택영역에 저장된다고 알고있다.
하지만 Int? 형으로 저장된것은 참조형이 되어 힙영역에 저장되있다. 그래서 삼중 등호에서는 결과값이 다르다.
자료형 변환이 필요할때가 있다.
그럴 때는 아래 코드처럼 .to(변환할 자료형)()을 사용하자.
val a: Int = 1
val b: Double = a.toDouble()
하나의 꿀팁이 있다.
코틀린에서는 저장되는 값이 -128 ~ 127 범위에 있으면 캐시에 그 값을 저장하기에 성능이 빨라진다.
Number라는 자료형이 있다.
이것은 스마트 캐스트를 사용할 수 있는데, 스마트 캐스트는 컴파일러가 자동으로 형 변환을 하는것을 의미한다.
package chap02.section3
fun main(){
var test: Number = 12.2
println("$test")
test = 12 // int형으로 스마트 캐스트
println("$test")
test = 120L // Long형으로 스마트 캐스트
println("$test")
test += 12.0f // Float형으로 스마트 캐스트
println("$test")
}
자료형 검사하기
package chap02.section3
fun main(){
val num = 256
if(num is Int){
print(num)
}
else if (num !is Int){
print("Not a Int")
}
}
코틀린은 is 앞에 느낌표기호 (!)를 통해 not 연산을 할 수 있다.
또한 Int처럼 자료형을 직접 선언함으로써 자료형을 검사할 수 있다.
Any라는 자료형이 있는데, 이것은 코틀린의 최상위 기본 클래스로 어떤 자료형이라도 될 수 있는 특수한 자료형이다.
package chap02.section3
fun main(){
var a: Any = 1 // Any형 a는 1로 초기화 될 때 Int형이 됨
a = 20L // Int형이었던 a는 변경된 값 20L에 의해 Long형이 됨
println("a : $a type : ${a.javaClass}") // a의 자바 기본형을 출력하면 long이 나옴
}
자료형 검사와 Any를 종합한 예제이다.
package chap02.section3
fun main() {
checkArg("Hello")
checkArg(5)
}
fun checkArg(x : Any){
if (x is String){
println("x is String : $x")
}
if (x is Int) {
println("x is Int : $x")
}
}
main함수에서 처음에는 String형, 그 다음에는 Int형을 인자로 checkArg함수에 넘겨주었다.
checkArg함수의 인자는 Any형인데, 어떠한 형이 들어와도 받은 인자를 바탕으로 문자열을 점검할 수 있다.
6주차 - 프로퍼티와 초기화 (3) | 2024.01.09 |
---|---|
5주차 - 클래스와 객체의 정의 (1) | 2024.01.06 |
4주차 - 프로그램의 흐름 제어 (0) | 2024.01.04 |
3주차 - 함수와 함수형 프로그래밍 (0) | 2024.01.02 |
1일차 - 코틀린 시작하기 (1) | 2023.12.22 |
댓글 영역