코틀린 시작하기!

03-01 코틀린의 등장 배경
코틀린의 등장 배경
- JetBrains에서 오픈소스 그룹이 개발해서 만든 프로그래임 언어가 Kotlin 이다
- 2017년에 구글에서 안드로이드 공식 언어로 지정됨
- TMI: 자바가 인도네시아 섬 이름이면 코틀린은 러시아 섬 이름에서 유래
- 자바의 가상 머신인 JVM에 기반을 둔 언어이기 때문에 코틀린 실행 가능
- 코틀린이랑 자바는 다른 언어
○ 자바는 .java 코틀린은 .kt
○ 코틀린 컴파일러 (kotlinc)가 .kt 파일을 컴파일하면 자바 바이트 코드가 만들어진다

코틀린 장범:
- 표현력과 간결함
- 안전한 코드
○ 코틀린은 널 안전성(nulll safety) 을 지원하는 언어이다
○ 객체지향 프로그래임에서 객체는 null 이면 NullPointException 오류가 발생 가능성이있다
○ 코틀린에서는 변수를 널 허용(nullanle)과 not null 으로 구분해서 선언한다
- 상호 운용성(interoperable)
○ 코틀린과 자바는 100% 호환 가능
- 구주화 동시성 (structured concurrency)
○ 코틀린 언어가 제공하는 코루틴(coroutines)이라는 기법을 이영하면 비동기 프로그램을 간소화 할수 있다

코틀린 파일 구성
- 만약 User.kt 라는 코틀린 파일을 생성하면…
package 구문은 파일을 컴파일 했을 때 만들오자는 클랴스 파일의 위치를 나태나며 소스 파일에서 맨 처음 한 줄로 손온 § package 이름은 kt 파일의 위치와 상관없는 별도의 이름으로 선언 가능
§ 예) User.kt 파일의 이 com/example/test3 에 있더라다도 package ch3처럼 선언 가능
□ 이렇게 했을때 컴파일된 파일은 ch3 폴더에 생성된다
§ Import 구문은 package 구문 아래에 여러 줄 작성 가능
□ import 문 아래에 변수, 함수, 클래스를 선언할 수 있다
§ 어떤 파일에 선언한 멤버(변수, 함수, 클래스)를 다른 코틀린 파일에서 참조할 때 두 파일은 같은 package로 선언 했다면 import 없이 사용 가능
코틀린 소스를 테스트하는 방
- New => Kotlin Class/File => File 선택
fun main(){
println("hello world")
}
- 입력후
-
- 하면 hellow world가 출력됨

03-02 변수와 함수
변수 선언하기
- 코틀린에서 변수는 val, var 키워드로 선언한다
- 변수 선언 형식:
○ val (혹은 var) 변수명: 타입 = 값
예시)
val data1 = 10
var data2 = 10

fun main() {
data1 = 20 //오류
data2 = 20 //성공
}

- `val 키워드로 선언한 변수는 처음 할당한 값으로만 이용 가능…

타입 지정과 타입 추론
- 변수명 뒤에는 콜론(:) 을 추가해 타입을 명시할 수 있다
- 예)
val data1:Int = 10
val data2 = 10
○ data1은 명시적으로 Int 타입을 선언한 것이다
○ `data2는 대입한 값이 10이므로 자동으로 Int 타입이 된다
§ val data2:Int = 10 와 같다
초깃값 할당
- 최상위에 선언한 변수나 클래스의 멤버 변수는 선언과 동시에 초기값을 할당해야한다
- 함수 내부에 선언한 변수는 선언과 동시에 초깃값을 할당하지 않아도 된다
- 변수를 이용하려면 값을 할당하고 이용해야 한다

val data1:Int //오류
val data2 = 10 //성공

class User{
val data4: Int //오류
val data5: Int = 10//성공
}

초기화 미루기
- 변수를 선언할 때 초기밧을 할당할 수 없는 경우도 있다
○ 나중에 할다할 것이라고 컴파일러한테 알려주어야한다
- 'lateinit나 lazy 키워드를 이용
○ lateinit 키워드는 이후에 초깃값을 할당할 것임을 말한다

    lateinit var data1: Int //error
    lateinit val data2: String //error
    lateinit var data3: String //successful

- lateinit 조건:
	○ lateinit 은 var 키어드로 선언한 변수에만 사용 가능
	○ Int, long, Short, Double, Float, Boolean, Byte 타입을 사용이 불가능

- 'lazy  키워드는 변수 선언문 뒤에 by lazy { } 형식으로 선언한다
	○ 소스에서 변수가 사용되는 순간 증괄로 묶은 부분이 자동으로 실행되고 그 결괏값이 변수의 초깃값으로 할당됨
- 'lazy 문의 중괄호 부분을 여러 줄로 작성한다면 마지막 줄의 실행 결과 변수의 초깃값이 된다
예)

val data4: Int by lazy{
println("in lazy...")
10
}

fun main() {
println("in main....")
println(data4+10)
println(data4+10)
}

결과:
in main....
in lazy...
20
20

데이터 타입
- 코틀린의 모든 변수는 객체이다
○ 따라서 코틀린의 모든 타입은 객체 타입이다
- 정수를 다루는 타입이 Int인데 기초 데이터 타입(primitive type)이 아니라 클래스이다

fun someFun() {
var data1: Int = 10
var data2: Int? = null //null 대입 가능

data1 += 10
data1 = data1.plus(10) //객체의 메서드 이용 가능

}
- 만약 Int 타입이 기초 데이터 타입이라면 변수 null을 대입할 수 없으며 메서드를 호출할 수도 없다
○ 하지만 코틀린의 모든 타입은 객체이므로 정수뿐만 아니라 null 도 대입 가능

Int, Short, Long, Double, Float, Byte, Boolean -기초 타입 객체
- 기초 데이터를 객체로 표현하는 타입이다
○ 정수: Int, Short, Long
○ 실수: Double, Float
○ 2진수: Byte
○ 참거짓: Boolean
Char, String - 문자와 문자열
- Char는 문자를 표햔하는 타입이다
- String은 문자열을 표현하는 타입
○ String은 (") 나 (""")로 감싸서 표현한다
○ 만약 """ 한다면 \n 을 사용할 필요가 없고 자동으로 새로운 줄을 인식한다
○ 예)

	    val str = """
	        Hello
	        World
	    """
	결과:
	Hello
	Worl
	
	○ 참고로 Andriod Studio에서는 만약 """ 사용하면 자동으로 '.trimIndent()'가 붙는다
		§ 이 함수는 문자열 앞에 공백을 없애준다
- String 타입의 데이터에 변숫값이나 어떤 연산식의 결과값을 포함해야 할 때는 $ 기로를 사용해야한다
	○ 이를 문자열 텝플릿(String template) 이리고 한다
	○ Ex: println("name: $stringValue)

Any - 모든 타입 가능
- Any는 코틀린에서 최상위 클래스이다
- 모든 클래스는 Any의 하위 클래스이다

Unit - 반환문이 없는 함수
- Unit은 다른 타입과 다르게 데이터의 형식이 아닌 특수 상황을 표현하려는 목적으로 사용
- Unit 타입으로 선언한 변수에는 Unit 객체만 대입 가능
- Unit 타입으로 변수를 선언할 수 있지만 아무런 의미가 없다
- Unit 타입은 주호 함수의 반환 타입으로 사용된다
예시)
fun some(): Unit{
println(10+20)
}

fun main() {
println("in main....")
println(some())
}
=>
in main....
30
kotlin.Unit

Nothing - null이나 예외를 반환하는 함수
- Nothing은 Unit과 마찬가지로 의미 있는 데이터가 아니라 특수 상황을 표현하려는 목적으로 사용
- Nothing으로 선언된 변수에는 null만 대입 가능
○ 즉, Nothing으로 선언한 변수는 데이터로서는 의미가 없다
- 예) val data1: Nothing? = null
- Nothing은 주로 함수의 반환 타입에 사용
- Nothing이면 반환 하지면 의미 없는 값이라고 의미 한다
- 만약 항상 null 만 반환하는 함수라든가 예외를 던지는 함수의 반환 타입을 Nothing 으로 선언한다

널 허용과 불허용
- 코틀린의 모든 타입은 객체이므로 null 대입 가능
- 널 사용하기 위해서는…. (nullable ==null 사용 가능)
○ 변수 선언할 때 타입 뒤에 물음표(?)로 표시한다
○ 타입 뒤에 '?' 추가는 == 널 허용, 없으면 허용 않함
○ 예)
var data1: Int = 10
data1 = null //error

		var data2: Int? = 10
		data2 = null //correct

함수 선언하기
- 코틀린에서 함수를 선언하려면 fun 이라는 키워드를 이용해야한다
○ Ex: fun 함수명 (매개변수명 : 타입): 반환타입{…..}
○ Ex:
fun some(data1: Int): Int{
return data1+10
}
- 함수에서 반환 타입 선언을 생략하면 자동으로 Unit 타입이 적용된다
- 함수의 parameter 에는 var나 val 키워드를 사용이 할수 없다
- 'val이 자동으로 적영되는 함수 안에서 parameter 값을 변경 할수 없다
예)
fun some(data1: Int): Int{
data1 = 10 //error
}

- 함수의 매개변수에는 default value를 선언 가능
- 기본값을 선언했다면 인자(argument)를 전달 하지 않아도 되며 이때 선언문에 명시한 기본값이 적용됨

예)
fun main() {
fun some(data1: Int, data2: Int = 10): Int{
return data1*data2
}
println(some(10))
println(some(10,20))
}
=>
100
200

- 순서와 상관없이 매개변수명을 지정해서 순서를 바꿔도 가능
예)
fun main() {
    fun some(data1: Int, data2: Int = 10): Int{
        return data1*data2
    }
    println(some(data2=10,data1 = 20))
}
- 매개변수명을 지정하여 호출하는 것을 명명된 매개변수(named parameter)라고 한다

컬렉션 타입
- Collection type 이란 여러 개의 데이터를 표현하는 방법 (대표 예: Array, List, Set, Map)
Array - 배열
- Array 클래스의 생성자에서 첫 번째 매개변수는 배열의 크기이며 두 번째 매개변수는 초깃값을 지어하는 함수이다
- 배열의 타읍은 generic 으로 표현한다
○ Array 나 Array
- Array 클래스의 생성자
○ Ex:
(size: Int, init:(Int)->T)
- 배열 선언 예
○ val data1: Array = Array(3,{0})
- 배열의 데이터에 접근할 때는 대과화( [] ) 사용해도 되고 set() 이나 get() 함수를 이용 가능

기초 타입의 배열
- Array 는 타입을 명시하기 위해 generic을 사용하지만 기초 타입 Array는 불필요
○ 예) BooleanArray, ByteArray, CharArray, DoubleArray,FloatArray, IntArray, LongArray, ShortArray
- 사용 예)
val data1: IntArray = IntArray(3,{0})
val data2: BooleanArray = BooleanArray(3,{false})
- `arrayOf() 함수도 기초 타입을 대상으로 booleanArrayOf(), byteArrayOf(), charArrayOf(), doubleArrayOf(), floatArrayOf(), floatArrayOf(), intArrayOf(), longArrayOf(), shortArrayOf() 함수를 제공
○ 예)
val data1 = intArrayOf(10,20,30)
val data2 = booleanArrayOf(true,true,false)

List, Set, Map.,..,.
- List, Set, Map은 Collection 인터페이스를 타입으로 표현한 클래스이다
○ 통틀어 Collection type 클래스라고 불린다
- List: 순서가 있는 데이터 집합으로 데이터의 증복을 허용한다
- Set: 순서가 없으면 데이터의 증복을 허용하지 않는다
- Map: 키와 값으로 이루어진 데이터 집합으로 순서가 없으며 키의 증복은 허용하지 않는다

- Collection 타입의 클래스는 가변(mutable) 클래스와 불변(immuratble) 클래스로 나눈다
	○ 불변(immuratble) 클래스는 초기에 데이터를 대입하면 더 이상 변경할 수 없는 타입이다
	○ 가변(mutable) 클래스는 초기값을 대입한 이후에도 데이터를 추가하거나 변경할 수 있다

구분 타입 함수 특징
List List listOf() 불변
MutableList mutableListOf() 가변
Set Set setOf() 불변
MutableList mutableSetOf() 가변
Map Map mapOf() 불변
MutableMap mutableMapOf() 가변

03-03 조건문과 반복문
조건문 if~else와 표현식
- if~else 문은 프로그램의 흐름을 제어하는데 가장 많이 사용됨
- 예)
if(data>= 10){
println(5)
}
else{
println(9)
}
- `else if 도 가능

조건문 when
- if~else 문 외에도 when 이라는 조건문을 사용 가능
- 예)
var data = 10
when(data){
10 -> println("is 10")
20 ->println("is 20")
else ->{
println("data is neither 10 nor 20")
}
}
- 예2)
var data: Any = 10
when(data){
is String ->println("valid")
20,30 ->println("valid") //데이터가 20 or 30
in 1..10 ->println("valid") //1부터 10 값이면
else ->{
println("data is not valid")
}
}

- 또한, when 문을 이용하면서 데이터를 명시하지 않고 조건만 명시 가능
	○ 예)
	var data  = 10
	    when {
	        data <= 0 ->println("data <= 0")
	        data > 10 ->println("data > 10") 
	        else ->println("valid") 
	    }
	결과 = valid

반복문 for 와 while
- if~else 문 외에도 when 이라는 조건문을 사용 가능
- 예)
var sum: Int = 0
for (i in 1..10){ //1~10
sum += i
}
println(sum)

- for (i in 1..10) => 1~10
- for (i in 1 until 10) => 1부터 9까지
- for (i in 2..10 step 2) => 2~10까지 2씩 증가
- for (i in 10..1 downTo 1) => 10~1 1씩 감소

- 증감 조건을 숫자로 명시하지 않고 컬렉션 타입의 개수만큼 반복 가능
- 예)
var data = arrayOf<Int>(10,20,30)
    for (i in data.indices){
        print(data[i])
        if(i !== data.size - 1) print(",")
    }

=> 결과: 10,20,30
- '.indices'는 컬렉션 타입의 인덱스값을 의미하므로 for문을 반복하면서 0,1,2 값을 i에 대입한다

- 만약 for문 하면서 인덱스와 실제 데이터를 함꼐 가져오려면 withIndex() 함수를 이용한다
	○ 예)
	var data = arrayOf<Int>(10,20,30)
	    for ((index, value) in data.withIndex()){
	        print(value)
	        if(index !== data.size - 1) print(",")
	    }
	=> 결과: 10,20,30
	
- 참고로 while문은 걍 그대로 사용하면 됨

좋은 웹페이지 즐겨찾기