최근 코틀린 개발에 관심이 많아져서 코틀린 기본 함수를 한번 정리하고 개발을 진행하기 위해 기초 문법을 정리했습니다.
메인 함수
fun main() {
print("Hello World!")
}
- 코틀린의 코드 끝에는 ;를 붙여도 실행이 되지만 안붙이는걸 지향한다.
- 코틀린은 메인 함수에서 실행된다
변수
fun main() {
var i = 10
var name = "재혁"
var point = 3.3
}
- 코틀린은 타입 추론기능을 갖고 있어서 타입을 지정해주지 않아도 된다.
- 타입을 지정하고 싶다면 변수 뒤에 : 타입명 을 입력해서 명시적 지정도 가능하다.
fun main() {
var i : Int = 10
var name : String = "재혁"
var point : Double = 3.3
}
- 코틀린에서 모든 타입들이 레퍼런스 타입을 갖고 있다.
- 대문자로 시작하는 래퍼 클래스 타입의 형식을 사용한다.
상수
fun main() {
val num = 20
num = 30 // 재 대입 불가능 -> 에러 발생
}
- java의 final과 동일하다.
톱 레벨 상수 const
const val num = 20
fun main() {
var i = 10
var name = "재혁"
var point = 3.3
}
- 반드시 모든 파일에 클래스가 필요 없고, 코틀린에서는 main 함수가 있으면 된다.
- 위 코드의 main함수 밖의 num 상수는 컴파일 타입의 상수이다.
- 메인 함수 보다 먼저 num이 컴파일된다.
형변환
fun main() {
var i = 20
var l = 20L
var name = "10"
i = name.toInt()
l = i.toLong()
i = l.toInt()
}
- 데이터 변환은 toXXX 함수를 사용한다.
String
fun main() {
var name = "hello"
// print(name.uppercase())
// print(name.lowercase())
// print(name[0])
print("제 이름은 ${name + 10} 입니다.")
}
max, min
import kotlin.math.max
fun main() {
var i = 10
var j = 20
print(max(i, j))
}
random
import kotlin.random.Random
fun main() {
val randomNumber = Random.nextInt(0, 100)
print(randomNumber)
println()
val randomNumber2 = Random.nextDouble(0.0, 1.0)
print(randomNumber2)
}
키보드 입력
fun main() {
val reader = Scanner(System.`in`) // in은 그 자체로는 코틀린에서 사용할 수 없다
reader.nextInt()
reader.next()
}
조건문
fun main() {
var i = 511
var result = if (i > 10) {
"10 보다 크다"
}
else if (i > 5) {
print("5 보다 크다")
}
else {
print("")
}
print(result)
}
fun main() {
var i = 511
var result = when {
i > 10 -> {
"10 보다 크다"
}
i > 5 -> {
print("5 보다 크다")
}
else -> {
print("")
}
}
print(result)
}
- 코틀린에서는 조건문의 리턴 값을 변수에 담을 수 있다
- if else문을 when else로 바꿔 쓸 수 있다
반복문
fun main() {
val items = listOf(1, 2, 3, 4, 5)
for (item in items) {
print(item)
}
for (i in 0..(items.size - 1)) {
print(i)
}
}
- break / continue 사용법 자바와 동일
List
fun main() {
val items = listOf(1, 2, 3, 4, 5) // 변경이 안되는 리스트
val items2 = mutableListOf(1, 2, 3, 4, 5) // 변경이 되는 리스트
items2.add(6)
items2.remove(3)
print(items2)
}
Array
fun main() {
val items = arrayOf(1, 2, 3)
try {
val item = items[4]
} catch (e: Exception) {
print(e.message)
}
}
Null Safety
- 코틀린에서 Null을 대입할 수 있는 경우는 타입명에 “?”를 입력해야 null을 대입할 수 있다.
!!
- 개발자가 임의로 null이 아님을 보장하는 방법
- null이 아니라면 실행되는 함수
name?.let {
}
함수
- 메소드 오버로드는 파라미터 값을 조정해서 디폴트값을 설정해 만들어줄 수 있다
fun main() {
print(sum(10,20))
}
fun sum(a: Int, b: Int, c: Int = 0) = a + b
Class
- Getter, Setter를 별도로 만들 필요 없이 val이나 var을 적절히 조절해서 같은 효과를 구현할 수 있다
fun main() {
val john = Person("John", 20)
print(john.name)
print(john.age)
john.age = 21
print(john.age)
}
class Person(val name: String,
var age: Int,)
data class
- 외부에서 접근을 차단할 경우 private 키워드를 필드에 붙여준다.
fun main() {
val john = Person("John", 20)
print(john.name)
print(john.age)
john.age = 21
print(john.age)
}
class Person(
private val name: String,
var age: Int,
)
getter, setter
- hascode(), toString()은 data 키워드를 클래스 앞에 붙여 편리하게 사용할 수 있다
fun main() {
val john = Person("John", 20)
val john2 = Person("John", 20)
println(john)
println(john2)
print(john == john2)
}
data class Person(
private val name: String,
var age: Int,
)
getter, setter 제어
fun main() {
val john = Person("John", 20)
val john2 = Person("John", 20)
println(john)
println(john2)
print(john == john2)
john.some()
print(john.hobby)
}
data class Person(
private val name: String,
var age: Int,
) {
var hobby = "축구"
init { // 생성될 때 실행된다.
print("init")
}
fun some() {
hobby = "농구"
}
}
- getter 재정의
fun main() {
val john = Person("John", 20)
val john2 = Person("John", 20)
println(john)
println(john2)
print(john == john2)
john.some()
print(john.hobby)
john.hobby = "야구" // 에러
print(john.hobby)
}
data class Person(
private val name: String,
var age: Int,
) {
var hobby = "축구"
private set
get() = "취미: $field"
init { // 생성될 때 실행된다.
print("init")
}
fun some() {
hobby = "농구"
}
}
상속 extends
자바는 모든게 허용되는 형태고 반대로, 코틀린은 모든게 허용되지 않는 형태
상속을 받아도 오버라이드가 안된다.
open 키워드로 함수 앞에 붙여줘야 오버라이드된다.
마찬가지로, 일반 클래스도 상속을 설계하려면 open 키워드를 붙여야 상속받는 클래스에 상속해줄 수 있다.
fun main() {
}
abstract class Animal {
open fun move() {
print("이동")
}
}
class Dog : Animal() {
override fun move() {
print("1")
}
}
class Cat : Animal() {
override fun move() {
print("2")
}
}
interface
fun main() {
val cat = Cat()
cat.move()
}
interface AnimalInterface {
fun move()
}
abstract class Animal {
open fun move() {
print("이동")
}
}
class Dog : AnimalInterface {
override fun move() {
print("1")
}
}
class Cat : Animal(), AnimalInterface {
override fun move() {
print("2")
}
}
타입 체크 is
fun main() {
val dog: Animal = Dog()
val cat = Cat()
if (dog is Cat) {
println("멍멍이")
}
}
interface AnimalInterface {
fun move()
}
abstract class Animal {
open fun move() {
print("이동")
}
}
class Dog : AnimalInterface, Animal() {
override fun move() {
print("1")
}
}
class Cat : Animal(), AnimalInterface {
override fun move() {
print("2")
}
}
- is로 타입을 체크할 수 있다
강제 타입 변환 as
fun main() {
val dog: Animal = Dog()
val cat = Cat()
if (dog is Cat) {
println("멍멍이")
}
cat as Dog
}
- Generic 타입
fun main() {
val box = Box(10)
val box2 = Box("dfsdfd")
print(box.value)
}
class Box<T>(var value: T)
콜백함수(고차함수)
fun main() {
myFunc(10) {
println("함수 호출")
}
}
fun myFunc(a: Int, callBack: () -> Unit) {
println("함수 시작!!!")
callBack()
println("함수 끝!!!")
}
코루틴
- suspend 키워드: 해당 함수가 완료될 때까지 기다린다.