– 편안함을 추구하는 언어
– 간결함을 추구하는 언어
– 명령형 언어, 객체 지향 언어에서의 기능적 언어 개념
– 실용성
– 이미 검증되고 널리 알려진 언어 기능 채택
– 간결함
– 유형 추론(유형을 지정할 필요 없음), getter/setter
– 안정성(제로 보안)
– 상호 운용성(Java와 100% 호환성)
– 다양한 플랫폼 지원
– JVM 기반 서버, Android, Kotlin JavaScript, Kotlin 네이티브 IOS, MacOS, AndroidNDK, Windows, Linux
– 정적으로 입력된 언어
– 정적으로 입력된 lang. (자바, 코틀린)
– 동적으로 입력된 언어. (파이썬)
– 기능적 언어
– 오픈 소스(Kotlin의 새로운 기능을 만들 수 있음)
Java와 달리 Kotlin은 소스 파일의 위치 및 이름 지정에 대한 제한이 없습니다.
– 하나의 파일에 여러 클래스를 넣을 수 있습니다.
– 패키지 구조와 디렉토리 구조가 일치하지 않아도 됩니다.
패키지 com.example.mykotlin
/* 이 파일은 com/example/mykotlin/에 있을 필요가 없습니다.
이 파일의 이름은 원하는 대로 지정할 수 있습니다 */
재미있는 메인() {
println(“안녕, 코틀린”)
// Kotlin은 세미콜론이 필요하지 않습니다.
}
//Java와 달리 main() 함수는 독립적으로 존재합니다.
Kotlin에서 변수를 선언하는 키워드는 val과 var입니다.
– 변수 선언 키워드 뒤에 변수명, 콜론, 타입을 적는다.
-val
– val(?)로 선언된 변수는 허용되지 않음 -> 초기화 시 값 변경 불가
– 변수라고 부르지 말고 값이라고 부르세요.
– val 자체는 value의 줄임말입니다.
-var
var로 선언된 변수는 변경 가능
– 변수의 약자
값 a: Int = 10
변수 b: 정수 = 12
//a=11// 컴파일 오류
b = 13 // 확인
*발 a = 객체
개체의 멤버 변수 값을 변경할 수 있습니다.
그러나 a의 값을 변경하는 것은 불가능합니다.
– Kotlin 변수를 선언할 때 타입을 사용하지 않아도 컴파일러는 할당된 값을 기반으로 타입을 자동으로 결정합니다.
Java와 달리 Kotlin은 기본 유형과 래퍼 유형을 구분하지 않습니다.
– 바이트, Short, Int, Long, Float, Double, Char, Boolean
– UByte, UShort, UInt, ULong
Kotlin은 서로 다른 유형의 값을 자동으로 변환하지 않기 때문에 명시적으로 값을 변환해야 합니다.
값 i = 10
값 i2: UInt = 10U
//vale lov : Long = i// 컴파일 오류
val lov2 : Long = i.toLong() //명시적 값 캐스트(i.toLong()은 멤버 함수 메서드임)
– 구문은 Java와 유사하지만 Kotlin에서는 if를 명령문이 아닌 표현식으로 사용할 수 있습니다.
– 즉, if 문의 결과로 어떤 값이든 얻을 수 있습니다.
val x = if(a>10) “크다” 아니면 “작다”
– Kotlin에는 Java의 Object와 유사한 개념인 Any가 있습니다.
– Kotlin은 프리미티브 유형에 대해 Any를 지원합니다.
– 유형 테스트
– A는 유형입니다.
값 t : 모두 = 10
println((t는 int)) // 참
– A형을 B형으로 -> A형을 B형으로 변경(A와 B는 상호 상속)
재미있는 메인() {
재미있는 테스트(obj : Any){
if(obj는 Int입니다.) println(“obj는 Int입니다.”)
if(obj는 문자열입니다.) println(“obj는 문자열입니다.”)
println(“Obj를 문자열로 인쇄 > ${(Obj as? String ? : “”)}”})
}
시험(1)
// 객체는 int
// 객체를 문자열로 출력 > “”
테스트(“문자열”)
//obj는 문자열입니다.
//Obj를 문자열로 인쇄 > 문자열
– Java에서는 문자열 중간에 변수 값을 추가할 때 “+” 연산자를 사용했습니다.
Kotlin을 사용하면 변수(심지어 표현식)를 문자열에 넣을 수 있습니다.
– 삼중 따옴표가 있는 문자열 -> ‘ “”” ‘
– 모든 문자를 이스케이프 없이 작성할 수 있습니다.
– 여러 줄 문자열도 가능
var 버전=”1.3.50″
val javaStyle = “Hello, Kotlin” + 버전 + “!” -(하나)
val kotlinStyle = “안녕하세요, Kotlin ${version}!” -(2)
-> (1), (2)는 같다
값 번호 = 10
println(“val num은 10과 같습니다 : ${num==10}”)
println(“””\$”””) -> \$
println(“\$”) -> $
– Java와 달리 ‘==’ 연산자는 ‘객체 내용’을 비교하는 데 사용되며 ‘===’ 연산자는 ‘객체 참조’를 비교하는 데 사용됩니다.
Java에서 equals()는 객체 내용을 비교하는 데 사용됩니다.
== 연산자를 사용하여 문자열을 비교할 수도 있습니다.
데이터 클래스 MyClass(val a:Int, val b:String)
//데이터 클래스는 자동으로 equals/HashCode/toString/copy를 생성합니다.
재미있는 메인() {
val str1 = “안녕하세요, 코틀린”
var str2 = “안녕하세요, 코틀린”
값 Class1 = MyClass(10, “Class1”)
값 Class2 = MyClass(10, “Class1”)
값 Class3 = MyClass(20, “Class1”)
// 세 개체의 참조가 다릅니다.
println(str1==str2) //true(문자열 비교)
println(class1==class2) //true(문자열 비교)
println(class==class3) //false(문자열 비교)
println(class1===class2) //false(참조가 다르기 때문에)
– 배열은 arrayOf(), arrayOfNulls(), emptyArray()로 생성됩니다.
재미있는 메인() {
val intArrays = arrayOf(1,2,3,4,5) //유형 변환(int)이 필요하지 않음
val strArrays = arrayOfNulls
val dbArrays = 빈 배열
println(intArrays(0)) // 배열 인덱스에 해당하는 값
intArrays(0) = 10 //val에 의해 정의된 배열이지만 배열의 값은 변경 가능
println(intArrays(0))
for(strArrays의){
인쇄(“$s, “)
}
프린트(“”)
println(dbArrays.size) // 배열의 크기
}
반복자와 함께 for 문을 사용하는 것이 편리합니다.
Range를 사용하여 특정 범위에 대한 반복자를 만들 수 있습니다.
– 범위는 첫 번째와 마지막 숫자(또는 문자)를 …로 연결합니다.
– 예) 1..10, ‘a’..’z’ (‘.’ – 2)
함수 메인(){
val array = arrayOf(“hello”, “that”, “is”, “Kotlin”)
for(a in array) //배열 인터레이터
인쇄(“$a”)
println(“”) //안녕하세요 코틀린입니다.
for((idx, a) in array.withIndex()) // 인덱스 포함
인쇄(“($idx, $a)”)
println(“”) //(0, 안녕하세요) (1, this) (2, is) (3, 코틀린)
for(i in 1..10) //범위 포함
인쇄(“$i”)
println(“”) //1 2 3 4 5 6 7 8 9 10
for(i in 1..10 step 2) // 범위 및 단계 포함
인쇄(“$i”)
println(“”) // 1 3 5 7 9 (2씩 점프)
(10 downTo 1).forEach{ //람다 포함(downTo 역방향)
print(“$it”) // 기본 인수입니다.
}
println(“”) //10 9 8 7 6 5 4 3 2 1
// ‘while’을 사용하는 경우
변수 나는 = 0
동안(i<10){
나++
인쇄(“$i”)
}
println(“”) //1 2 3 4 5 6 7 8 9 10
}
– 재미있는 함수 이름(매개변수 목록): 반환 유형 {함수 정의}
– fun function name (parameter list) = expression // 함수의 내용을 한 줄로 표현할 수 있다면
– 함수의 내용이 표현식인 경우 리턴 타입을 유추할 수 있으므로 생략한다.
– 기본 인수가 지원됨 – 인수가 제공되지 않은 경우 사용됨
– 명명된 인수 지원 – 인수 지정 시 매개변수 이름 및 값 지정에 사용
fun myFunc(arg1: Int, arg2: String = “default”, arg3: Int = 10)
{
println(“$인수1, $인수2, $인수3”)
}
재미있는 sumFunc(a: Int, b: Int) = a+b
재미있는 메인() {
myFun(1, “안녕하세요”, 5) //1, 안녕하세요, 5
myFun(arg1=2) //2, 기본값, 10
myFunc(2, arg3=5) //2, 기본값, 5
//로컬 함수
재미있는 localFunc(a: Int) : Int{
+ 10 반환
}
println(sumFunc(1,2)) //3
println(localFunc(10) //20
}
– Lambda 함수는 {argument list -> function content} 형식으로 작성
– 인자가 1개이고 타입 생략이 가능한 경우 기본 인자를 이용하여 인자 목록 부분 생략 가능
– 람다함수는 별도의 리턴을 사용하지 않으므로 (x+y)식으로 표현한다.
val sum = {x: Int, y: Int -> x+y} // 람다 함수 정의
println(합계(10, 20))
fun lambdaTest(a: (Int) -> Int) : Int{ //(int) 인자를 받아 int를 반환하는 타입
a(10)를 반환합니다.
}
lambdaTest({x -> x+10}) //ie {x: Int -> x+10}
lambdaTest({it + 10}) //인수 타입은 생략 가능, 인수는 1개이므로 인수 목록 생략
lambdaTest{it + 10} //lambda가 함수의 유일한 인수인 경우 함수 괄호를 생략할 수 있습니다(lambdaTest 함수의 인수 {it+10}로 지정됨).
데이터 클래스 MyClass(val a: Int, val b: String)
재미있는 LambdaTest (a: (int) -> int): int {
}
재미있는 메인() {
합계 = {x: 정수, y: 정수 -> x+y}
println(합계(10, 20))
배열 배열 = arrayOf(MyClass(10, “class1”), MyClass(20, “class2”), MyClass(30, “class3”))
println(array.filter({c: MyClass -> ca < 15})) //(MyClass(a=10, b=class2))
//Filter는 함수를 매개변수로 받아 각 요소에 대한 함수의 조건에 따라 실행하고 참 값만 씁니다.
//c는 MyClass를 수신하고 MyClass의 속성 a의 조건은 15 미만입니다.
//함수의 마지막 인자로 람다를 사용하면 함수의 괄호에서 빼낼 수 있다.
array.filter() {c:MyClass -> ca < 15}
// 람다가 함수의 유일한 인수인 경우 함수 대괄호를 생략할 수 있습니다.
array.filter{c: MyClass -> ca <15}
//인수 타입을 생략할 수 있는 경우
배열.필터 {it.a < 15}
//표준 매개변수 이름으로 사용할 수 있으며 일반적으로 사용되는 형식입니다.
인쇄(lambdaTest{it + 10})
val title=”숫자:”
값 목록 = ListOf(1,2,3,4)
list.forEach{println(“$title $it)} //람다 외부의 제목에 액세스
}
– Android 프로그래밍에서 자주 사용되는 예제
1- 값 btn = findViewById
– switch 문과 유사하나, 경우에 따라 타입이 다를 수 있으며 표현식으로 사용할 수 있습니다.
재미있는 테스트(arg : Any) {
언제 (인수) {
10 -> println(“10”)
0..9에서 -> println(“0
is 문자열 -> println(“Hello, $arg”) -> ‘is’ 유형 검사
!in 0..100 -> println(“x < 0 und x>100″)
그렇지 않으면 -> {
println(“알 수 없음”)
}
}
}
– nullable과 nonnullable 타입 구별
– 유형 이름 뒤에 “?”가 추가되면 Nullable 유형
import java.lang.NullPointerException
fun testNull(arg : String?) //문자열? -> null 값을 포함할 수 있음
{
println(arg?.uppercase()) // 인자? arg가 null이면 null 반환
println(arg?.uppercase()? : “-“)
//Elvis(?:)는 왼쪽 피연산자가 0이면 오른쪽 피연산자(“-“)를 반환합니다.
}
재미있는 메인() {
var nullable: 문자열? = 0
var nonNullable: 문자열 = “nonNullable”
//nonNullable = null // 컴파일 오류
testNull(nonNullable) //NONNULLABLE NONNULLABLE
testNull(널 입력 가능) //널 –
//nullalble.uppercase() //컴파일 오류
nullable?.uppercase() //nullable이 null이므로 null을 반환합니다.
시도{
nullable!!.uppercase() // 예외 발생!
}catch(e : NullPointerException){
println(“널포인터 예외”)
}
}
– Try 및 catch 문은 Java와 거의 동일하며 표현식은 try 및 catch 문에 사용할 수 있습니다.
Java와 달리 Kotlin은 모든 예외를 포착하도록 강제하지 않습니다.
재미있는 메인() {
값 x = 시도 {
구문 분석(“10”)
}잡기(전자: NFE) {
0
}
println(x) // 파싱이 성공하면 x에 10, 오류가 있으면 0이 입력됨
}
– Array(배열 크기는 변경 불가, 값은 변경 가능), List, Set, Map(불변: 내용 변경 불가)
– ArrayList(배열의 크기와 값을 변경할 수 있음), MutableList, MutableSet, MutableMap(변경 가능)
값 배열 = arrayOf(1,2,3)
val arrayList = array.toMutableList() //arrayListof(1,2,3)
값 목록 = listOf(1,2,3)
val mutableList = list.toMutableList() //mutablsListOf(1,2,3)
값 세트 = setOf(1,2,3,3)
val mutableSet = set.toMutableSet() //mutableSetOf(1,2,3,3)
val map = mapOf(“1″을 1로, “2”를 2로, “3”을 3으로)
val mutableMap = map.toMutableMap() //mutableMapOf(“1″을 1로, “2”를 2로, “3”을 3으로)
– 빈 컬렉션 만들기, 반복
재미있는 메인() {
value_array = arrayListOf
val e_list = mutableListOf
val e_set = mutableSetOf
val e_map = mutableMapOf
e_array.add(“1”)
e_list.add(1)
e_set.add(1)
e_map(“하나”) = 1
for(e_array의 a) print(“$a”)
for(e_list의 a) print(“$a”)
for(a in e_set) print(“$a”)
for((k, v) in e_map) print(“$k – $v”)
}

