[kotlin] 코틀린 언어 소개

ywown·2021년 11월 3일
0

코틀린 개념

목록 보기
1/8
post-custom-banner

『Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린』 교재를 바탕으로 정리한 내용입니다.

1. 코틀린 언어 소개

자바와 비교 시 특징

  • 프로그램 작성 시, 코틀린의 최신 언어 기법 활용해 훨씬 간결한 코드로 구현이 가능하다.
  • 널 안정성(null safety)을 지원한다. 변수를 null과 not null로 구분해 선언하므로 널과 관련된 부분들을 컴파일러가 해결해 준다.
  • 자바와 100% 호환되므로 자바 클래스나 라이브러리 활용 가능하다.
  • 코루틴(coroutines)이라는 기법을 이용해 비동기 프로그래밍을 비교적 간단하게 작성할 수 있다.

코틀린 파일 구성

  • 패키지, 임포트, 변수, 함수, 클래스 로 구성
  • 어떤 파일에 선언한 멤버를 다른 코틀린 파일에서 참조하는 경우, 두 파일을 같은 package로 선언했다면 import 없이 사용 가능
  • 코틀린은 파일명과 클래스명 다르게 선언 가능! → 변수, 함수 등을 클래스로 묶지 않고 최상위에 선언할 수 있기 때문에 상관 없음

2. 변수와 함수

변수

변수 선언

  • 기본 선언 형식 val(혹은 var) 변수명: 타입 = 값 대입하는 값을 통해 타입을 유추할 수 있는 경우에는 타입 생략 가능
  • 변수 선언 시 val / var 키워드 사용 val : value의 줄임말로, 초깃값이 할당되면 이후에 값을 변경할 수 없다. var : variable의 줄임말로, 초깃값이 할당된 후에도 값을 변경할 수 있다.
  • 초깃값 할당 최상위에 선언한 변수나 클래스의 멤버 변수는 선언과 동시에 초깃값을 할당해야 한다. 내부에 선언한 변수는 선언과 동시에 초깃값을 할당하지 않아도 된다. → 초깃값을 변수 선언 후에 할당하고 싶은 경우에는 lateinit / lazy 키워드 사용 lateinit : 이후에 초깃값을 할당할 것이라고 명시적으로 선언한다. lateinit 사용 시 규칙 var 키워드로 선언한 변수에만 사용 가능 Int, Long, Short, Double, Float, Boolean, Byte 타입에는 사용 불가능
    lateinit var data1: Int      // 오류!
    lateinit var data2: String   // 성공!
  • lazy : 변수 선언문 뒤에 by lazy { } 형식으로 선언한다. 소스에서 변수가 최초로 이용되는 순간 중괄호 안의 내용이 자동으로 실행되어 그 결괏값이 변수의 초깃값으로 할당된다.
    val data3: Int by lazy {
    	println("example")
    	10
    }
    
    fun main() {
    	println(data3 + 10)       // "20" 출력
    }

데이터 타입

❗ 코틀린의 모든 변수는 객체이므로 코틀린의 모든 타입은 객체 타입

  • 기초 타입
    • 정수 표현 : Int / Short / Long
    • 실수 표현 : Double / Float
    • 2진수 표현 : Byte
    • true/false 표현 : Boolean
  • 문자와 문자열 타입
    • Char
      문자 표현하는 타입. 문자를 작은따옴표(')로 감싸서 표현
      Number 타입은 표현 불가

    • String
      문자열 표현하는 타입. 문자열을 큰따옴표(")나 삼중 따옴표(""")로 감싸서 표현
      String 타입의 데이터에 값을 포함해야 할 때 '$'기호(문자열 템플릿) 사용

      val subject: String = "kotlin"
      val score1: Int = "90"
      val score2: Int = "10"
      println("subject : $subject, score : ${score1}, sum : ${score1 + score2}")
  • Any
    Any는 코틀린에서 최상위 클래스
    Any 타입으로 선언한 변수에는 모든 타입의 데이터 할당 가능
  • Unit
    함수에서 반환문이 없음을 명시적으로 나타낼 때 사용
    Unit 타입의 변수에는 Unit 객체만 대입할 수 있기 때문에 변수 선언은 할 수 있지만 의미 없음
    fun some(): Unit {
    	println(10 + 20)
    }
  • Nothing
    항상 null만 반환하는 함수나 예외를 던지는 함수의 반환 타입을 Nothing으로 선언
    함수의 반환 타입이 Nothing인 경우, 반환은 하지만 의미 있는 값은 아님을 의미
    Unit과 비슷하게 Nothing 타입의 변수에는 null만 대입할 수 있기 때문에 변수 선언은 할 수 있지만 의미 없음
    fun some2(): Nothing? {
    	return null
    }
    
    fun some2(): Nothing {
    	throw Exeption()
    }
  • 널 허용(nullable) 불허용(not null) 코틀린에서는 변수 선언 시 null 대입이 가능한 변수인지 아닌지 명확하게 구분해서 선언해야 함
    • ?
      변수 선언 시 타입 뒤에 물음표를 추가하면 널 허용을 의미
      반대로 물음표를 추가하지 않으면 널 불허용으로 선언
    var data1: Int = 10
    data1 = null       // 오류!
    
    var data2: Int? = 10
    data2 = null       // 성공!

함수

함수 선언

  • 기본 선언 형식 fun 함수명(매개변수명: 타입): 반환타입 { ... }
    반환 타입 생략 시 자동으로 Unit 타입 적용
    fun example(data1: Int): Int {
    	return data1 * 10
    }
    
    fun sum(a: Int, b: Int) = a + b
  • 함수 매개변수는 var / val 키워드 사용 불가
  • 함수 매개변수에는 기본값 선언 가능

컬렉션

Array

  • 코틀린의 배열은 Array 클래스로 표현하며, 배열 타입은 제네릭으로 표현

    제네릭 : 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법

  • 배열의 데이터가 기초 타입이라면 Array가 아닌 기초 타입의 배열을 나타내는 클래스 이용 가능
  • 비어있는 배열을 선언할 때에는 arrayOfNulls()emptyArray()로 배열 객체 생성 가능
  • 또한 arrayOf() 함수를 이용해 배열 선언 및 값 할당 가능.
    arrayOf()도 기초 타입을 대상으로 하는 클래스 제공

    Array 클래스arrayOf() 함수
    - arrayOf()는 선언 시 원소 값들을 지정해줄 수 있지만, Array를 선언할 때에는 불가능
    - 대신 Array는 람다식 활용 가능

    // 첫번째 인자가 3이고 두번째 인자는 0을 반환하는 람다 함수
    // 0으로 초기화한 데이터를 3개 나열한 정수형 배열 선언
    val data1: Array<Int> = Array(3, { 0 })
    
    // 기초 타입 배열 선언
    val data2: IntArray = IntArray(3,{ 0 })
    val data3: BooleanArray = BooleanArray(3, { false })
    
    // arrayOf() 함수 이용해 선언
    val data4 = arrayOf<Int>(10, 20, 30)
    
    // arrayOf() 기초 타입 배열 선언
    val data5 = intArrayOf(10, 20, 30)
    val data6 = booleanArrayOf(true, false, true)
    
    // 비어있는 배열 객체 선언
    val data7 = arrayofNulls<String>(3)
    val data8 = emptyArray<String>

List / Set / Map

Collection 타입의 클래스는 가변(mutable)클래스와 불변(immutable)클래스로 나뉨

불변 클래스 : 데이터 대입 후 변경 불가

가변 클래스 : 초깃값 대입 후 데이터 변경 가능

→ List, Set, Map 모두 불변 타입이므로 동적으로 컬렉션을 이용하려면 MutableList, MutableSet, MutableMap 타입 활용

  • List : 순서가 있는 데이터 집합이며 중복을 허용한다.
  • Set : 순서가 없는 데이터 집합이며 중복을 허용하지 않는다.
  • Map : 키와 값으로 이루어진 데이터 집합으로 순서가 없으며 키의 중복은 허용하지 않는다.
// List
var list = listOf<Int>(10, 20, 30)
var mutableList = mutableListOf(10, 20, 30)

// Set
var set = mutableSetOf("A", "B")

// Map
// Pair 객체 또는 '키 to 값' 형태로 이용
var map = mapOf<String, String>(Pair("one", "hello"), "two" to "world")

3. 조건문과 반복문

조건문

if~else와 표현식

  • 기본적인 문법은 대부분의 프로그래밍 언어에서 제공하는 조건문과 차이 없음
  • 코틀린에서는 if~else를 표현식으로도 사용 가능
  • if~else 표현식에서는 여러 줄로 작성하더라도 마지막 줄의 실행 결과만 반환
  • 표현식으로 사용하는 경우 else 구문 필수로 있어야 함(생략 불가)
fun main() {
	var data = 10
	val result = if(data > 0) {       // 조건문 결과값을 result 변수에 대입
		println("data > 0")
		true       // 참일 때 반환값
	} else {
		println("data <= 0")
		false      // 거짓일 때 반환값
	}
	println(result)
}

when

  • 자바에서의 switch문과 비슷한 문법
  • when 문의 조건은 데이터 타입이나 범위 등으로 다양하게 명시 가능하고, 정수가 아닌 다른 타입도 가능
  • 데이터 명시하지 않고 조건만 명시하는 것도 가능
  • if~else 표현식과 마찬가지로, when문을 표현식으로 사용하는 경우에는 else 구문 생략 불가
fun main() {
	var data: Any = 10
	when ~~(data)~~ {       // 데이터 생략가능
		is String -> println("data is String")
		20, 30 -> println("data is 20 or 30")
		in 1..10 -> println("data is 1..10")
		else -> println("data is not valid")
	}
}

반복문

for

  • 조건에는 주로 범위 연산자 in 사용 for(i in 1..10) → 1부터 10까지 1씩 증가 for(i in 1 until 10) → 1부터 9까지 1씩 증가(10 미포함) for(i in 2..10 step 2) → 2부터 10까지 2씩 증가 for(i in 10 downTo) → 10부터 1까지 1씩 감소
  • 컬렉션 타입의 데이터 개수만큼 반복하려면 indices 또는 withIndex() 함수 사용
    • indices : 컬렉션 타입의 인덱스값 의미
    • withIndex() : 인덱스와 실제 데이터를 의미
fun main() {
	var data = arrayOf<Int>(10, 20, 30)
	for(i in data.indices) {
		print(data[i])
	}
}
fun main() {
	var data = arrayOf<Int>(10, 20, 30)
	for((index, value) in data.withIndex()) {
		print(value)
	}
}

while

  • 대부분의 프로그래밍 언어에서 제공하는 문법과 차이 없음
  • 조건이 참인 동안 {} 내부 영역 반복 실행
fun main(args: Array<String>) {
	var x = 0
	var sum1 = 0
	while (x < 10) {
		sum1 += ++x
	}
	println(sum1)
}
profile
기록
post-custom-banner

0개의 댓글