JetBrains에서 오픈소스 그룹을 만들어 개발한 프로그래밍 언어이다.
JVM에 기반을 둔 언어로 코틀린 컴파일러가 .kt 파일을 컴파일하면 자바 바이트 코드를 생성해준다.
val : value의 줄임말로 초깃값이 할당되면 바꿀 수 없는 변수var : variable의 줄임말로 초깃값이 할당되면 할당된 후에도 값을 바꿀 수 있는 변수최상위에 선언한 변수나 클래스의 멤버 변수는 선언과 동시에 초깃값을 할당해야하지만 함수 내부에 선언한 변수는 선언과 동시에 초깃값을 할당하지 않아도 된다.
val data1 : Int //error
val data2 = 10
fun ma(){
val data3: Int
}
by lazy { } 형식을 선언해 소스에서 변수가 최초로 이용되는 순간 중괄호로 묶은 부분이 자동 실행되어 그 결괏값이 변수 초깃값으로 할당된다.
해당 함수의 마지막 줄의 실행 결과가 변수의 초깃값이 된다.
val data4: Int by lazy{
println("in lazy...")
10
}
$ 기호 사용?를 붙이면 널 허용, 붙이지 않으면 널 불허용으로 선언함수 선언 시 fun이라는 키워드를 사용하면 반환 타입을 선언할 수 있으며 기본적으로 Unit 타입이 적용된다. 함수의 매개변수에는 val 키워드가 자동으로 적용되며 함수 내에서 매개변수 값을 변경할 수 없다.
Array val data1: Array<Int> = Array(3, {0})
val data1: IntArray = IntArray(3, {0})
val data1 = intArrayOf(1, 2, 3)
val data1 = arrayOf<Int>(1, 2, 3)
다음과 같은 형식으로 선언이 가능하다.
List, Map, Setmutable을 적어주면 된다val list = listOf<Int>(1, 2, 3)
val set = setOf<Int>(1, 2, 3)
val map = mapOf<String, String>(Pair("one", "world"), "one" to "hello")
map의 경우 위의 코드와 같이 선언할 수 있다.
for(i in 1 .. 10) : 1부터 10까지 1씩 증가for(i in 1 until 10) : 1부터 9까지 1씩 증가for(i in 1 .. 10 step 2) : 1부터 10까지 2씩 증가for(i in 10 downTo 1) : 10부터 1씩 1 감소indices 사용withIndex( ) 함수 사용 fun main(){
var data = arrayOf<Int>(1, 2, 3)
for(i in data.indices){
print(data[i])
}
for((index, value) in data.withIndex()){
print(value)
}
}
class main (name: String, count: Int){
init{
println("init")
}
fun some(){
println("name: $name, count: $count") //error
}
}
위의 같은 코드는 에러가 난다. 주생성자의 매개변수는 일반 함수에서 접근할 수 없다. 이때 주 생성자 매개변수를 var, val로 선언해주면 일반 함수에서도 접근 가능해진다.
class main (name: String, count: Int){
constructor(name: String, count: Int, address: String): this(name, count){
println("hello")
}
constructor(name: String, count: Int, address: String, age: Int): this(name, count, address){
println("hello2")
}
}
이런식으로 보조 생성자에서 this()를 사용해 주 생성자 및 다른 보조 생성자를 호출할 수 있다.
어떤 클래스를 상속받으려면 선언부에 콜론과 함께 상속받을 클래스 이름을 입력해준다. 다른 클래스에서 상속할 수 있게 선언하려면 부모 클래스에서 open 키워드를 사용하면 된다. 이때 자식 클래스에서 재선언한다면 override 키워드를 사용해주면 된다.
open class Super{
open var some = 10
open fun some() {
println("parent")
}
}
class Sub: Super(){
override var some = 20
override fun some(){
println("child $some")
}
}
데이터 클래스는 VO 클래스를 편리하게 이용할 수 있는 방법을 제공하며 data 키워드를 이용해 선언한다.
data class Dataclass(val name: String, val email: String, val: Int)
equals() : true, false의 결과 반환한다. 이때 비교는 주생성자에 선언된 매개변수만을 비교한다.toString() : 데이터 클래스를 사용하면서 객체가 가지는 값을 확인해야할 때 주로 사용한다.선언과 동시에 객체를 생성한다.
open class Super{
open var data = 10
open fun some() {
println("i am super")
}
}
val obj = object: Super(){
override var data = 20
override fun some(){
println("iam object")
}
}
fun main(){
obj.data = 30
obj.some()
}
멤버 변수나 함수를 클래스 이름 단위로 접근하고자 할 때 사용한다.
class MyClass{
companion object{
var data = 10
}
}
fun main(){
MyClass.data = 20
}
익명 함수 정의 기법으로 함수이지만 fun 키워드를 사용하지 않는다. 따로 return 문을 사용하지 않으며 함수의 반환값은 함수 본무늬 마지막 표현식이다.
이때 매개변수가 1개이면 매개변수를 선언하지 않아도 it 키워드로 매개변수를 이용할 수 있으며, 해당 매개변수의 타입을 식별할 수 있을 때만 사용 가능하다.
val some: (Int) -> Unit = {println(it)}
val some = {no1: Int, no2: Int ->
println("lambda")
no1+no2 //some의 값이 됨
}
이때 typealias를 사용해서 타입을 지정해줄 수 있다.
typealias MyFunType = (Int, Int) -> Boolean
fun main(){
var data1: MyFunType = {no1: Int, no2: Int ->
println("myfuntype")
true
}
객체가 null인 상황에서 널 포인터 예외가 발생하지 않도록 연산자를 비롯해 여러 기법을 제공한다. 이때 널 포인트 예외가 발생하지 않도록 하기 위해 널 안전성 연산자를 사용한다.
? : 변수 타입을 널 허용과 널 불허용으로 구분하고자 할 때 사용?.: 널 허용을 한 변수는 다음과 같은 연산자로 접근해야 함?: : 널 일때 대입해야 하는 값이나 실행해야 하는 구문이 있는 경우!! : 객체가 null일 때 예외를 발생시키는 연산자