What is Kotlin?
- Cross-platform,
- statically typed(정적타입 언어),
- JVM-targeted programming language Built-in null safety support
정적 타입 언어: 컴파일 시 변수의 타입이 설정되고, 그 이후로 타입은 변화하지 않는다.
동적 타입 언어: 런타임에 변수의 타입이 결정된다.
온라인 코틀린 컴파일러
Basic syntax
kotlin은 ; 사용하지 않음
같은 줄에 multiple statement 작성할 때만 세미콜론(;) 사용
ex)
val mynumber = 10; println(mynumber)
variable declaration
1. val: read-only local variables
can be assigned a value only one 초기에 값을 할당하면 나중에 값을 변경할 수 없다.
값을 변경하게 되면 컴파일 에러 발생
(java의 final과 유사)
val a: Int = 1
// val 변수명: 변수타입 = 값
// 변수타입 선언 권장
val b = 2
val c: Int
c = 3
2. var: variables that can be reassigned
var x = 5
x += 1
다른 타입의 값을 넣을 수 없다.
다른 타입의 값으로 재정의 한다면 타입 미스매치 Error 발생
string → “ ”
char → ‘ ‘
auto type casting 지원 (변수 타입 명시하지 않아도 됨)
If expression
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
fun maxOf(a: Int, b: Int) = if (a > b) a else b
When expression
conditional expression with multiple branches
C의 switch statement와 유사함
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
코틀린 컴파일러는 when이 표현식으로 사용될 때 else 부분이 존재하는지, 표현식이 가능한 모든 입력에 대해 값을 생성하는지 검증한다.
즉, when을 표현식으로 사용했는데 else가 없거나 처리할 수 없는 예외 입력 케이스가 있다면 컴파일러는 오류를 발생시킨다.
all cases가 covered 된다면 else을 사용하지 않아도 된다.
For loops
C#의 foreach loop와 유사하다.
val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}
val items = listOf("apple", "banana", "kiwi")
for (index in items.indices) {
println("item at $index is ${items[index]}"))
}
items.indices
for (x in 1..10 step 2) {
print(x)
}
for (x in 9 downTo 0 step 3) {
print(x)
}
// downTo로 역순 범위 지정
step
downTo
While loops
while: condition을 check한 뒤 조건 만족한다면 body를 실행하고 다시 condition check로 돌아간다.
do-while: body를 실행하고 condition을 check한다. 만족한다면 loop repeats.
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null)
while → 컨디션 판단 먼저
do while → 실행 후 컨디션 판단
Null safety
Kotlin은 null value를 default로 hold할 수 없다.
타입 시스템이 null이 가능한 참조와 그렇지 않은 참조를 구분한다.
null이 가능한 value라면 명시적으로 nullable하다고 mark해둬야 한다
var a: String = "abc"
a = null // 컴파일 에러 발생
val b: String ?= null
println(b?.length)
// returns b.length if b is not null,
// and null otherwise
?. null safe call operator
val l = if (b != null) b.length else -1
bob?.department?.head?.name
// 이 중 하나라도 null이라면 returns null
?.let
안전한 호출 연산자 let
→ null이 아닌 값에 대해서만 특정 연산 수행
ignores null
val listWithNulls: List<String?> = listOf("Kotlin", null)
for (item in listWithNulls) {
item?**.let** {println(it)} // prints Kotlin and ignores null
?: Elvis operator
null이 들어오면 다른 값/실행 코드를 반환해준다.
val l = b?.length ?: -1
// b.length가 null이 아니라면 그대로 return하고
// null이라면 -1를 return한다.
?: throw IllegalArgumentException("name expected")
!! not-null assertion
→ 값을 non-null type으로 변환해주고 value가 null이라면 exception(Null Point Exception) 발생
val l = b!!.length
// b.length가 null 아니라면 그대로 실행
// null 이라면 null point exception 발생
as? safe cast operator
어떤 값을 지정한 타입으로 캐스트
대상 타입으로 캐스트할 수 없어 failure 떴을 때 null 반환
val aInt: Int? = a as? Int
Functions
fun sum(a: Int, b: Int): Int {
return a + b
}
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
// return type 명시하지 않아도 됨
Unit: useful value를 return하지 않으면 return type은 Unit
Unit is a type with only one value
void와 비슷함
unit return type declaration 생략 가능
fun double(x: Int): Int = x * 2
fun double(x: Int) = x * 2
// explicitly declaring the return type is optional
// when this can be inferred by the compiler
collections overview
kotlin standard library는 basic collection type으로 sets, lists, maps를 제공한다.
read-only 불변: collection element에 접근하기 위한 기능을 제공한다.
mutable 가변: collection element를 더하거나 지우거나 변경하는 등의 기능을 제공한다.
참조자인 변수가 변경되는 것이 아니므로 꼭 var를 사용해야 하는 것은 아니다.
listOf → read-only
mutableListOf → mutable
val numbers = setOf(1, 2, 3, 4)
val numbersBackwards = setOf(4, 3, 2, 1)
println(numbers.first() == numbersBackwards.first()) // false
println(numbers.first() == numbersBackwards.last()) // true
List<T>
: 지정된 순서대로 element 저장.
0부터 시작하는 인덱스로 element 접근
길이가 같고 구조적으로 동일하면 동등한 list로 판단한다.
Set<T>
: 순서 없는 element 저장.
중복 없이 모든 element는 유일하며 null도 유일하므로 한 개만 가질 수 있다.
길이 같고 element 같으면 동등한 set으로 판단한다.
Map<K, V>
:key-value pairs 저장
key는 유일, 같은 value 가진 key 존재 가능
순서 상관 없이 같은 key-value 값들 가지면 동등한 map으로 판단한다.
val numberMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)
val numberMap = mapOf("key2" to 2, "key1" to 1, "key4" to 1, "key3" to 3)
println("The maps are equal: ${numberMap == anotherMap}") // true
creating classes and instances
class Shape // define a class
class의 properties는 declaration이나 body에 listed될 수 있다.
class Rectangle(var height: Double, var length: Double) {
var perimeter = (height + length) * 2
}
class간 상속은 콜론(:)으로 선언
class는 default가 final. 상속을 원한다면 mark it as open
open class Shape
class Rectangle(var height: Double, var length: Double): Shape() {
var perimeter = (height + length) * 2
}
상속을 해줄 클래스가 open을 해주어야 다른 클래스가 상속 받을 수 있다.
상속받을 클래스: 상위타입
Classes- Constructors
primary constructor는 상황에 따라 생략 가능
상황: annotation이나 접근 제한자
secondary constructors는 prefixed with constructor (생략 불가능)
primary constructor 있다면 각 secondary constructor는 primary constructor를 위임받아야 함
→ this
delegation to another constructor of the same class
같은 클래스의 다른 constructor에게 위임하는 경우 this keyword 사용
class Person(val name: String) {
val children: MutableList<Person> = mutableListOf()
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
// 여기서 name이 하나의 primary constructor
// 어노테이션이나 접근 제한자 갖고 있지 않다면 constructor 키워드 생략 가능
primary constructor 없더라도 delegation은 여전히 발생
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor $i")
}
}
init 블럭(primary constructor의 일부)의 코드는 항상 secondary constructor의 body보다 먼저 실행된다.
access control (modify state, help to expose only the data wish to expose…)
→ part of a larger object-oriented concept known as encapsulation
getter, setter
코틀린은 var 변수 만들어주기만 해도 getter, setter 내부적으로 컴파일 단계에서 자동으로 생성해줌
'SKKU SW > Mobile App Programming' 카테고리의 다른 글
[Kotlin] [Android Studio] Coroutine 사용하여 http 통신하기 (1) | 2024.05.15 |
---|