[ 앱 개발자 도전기 : 안드로이드_코틀린 ] 코틀린 기본 문법 훑어보기.-[1]
∇ 코틀린 기본 문법 훑어보기 - [1]
목 차
1. 변수
2. 자료형
3. 형 변환
4. 배열
5. 타입 추론
6. 함수
§ 세미콜론을 붙이지 않아도 됩니다.
fun main() {
println("Hello, world!!!")
}
§ 변수 선언시 파스칼, 카멜 표기법을 권장합니다.
파스칼 표기법 : ClassName
카멜 표기법 : className
Ⅰ. 변수 선언 방법
* var : 일반적으로 통용되는 변수, 언제든지 읽기-쓰기가 가능함., 변수값 변경 가능.
* val : 선언시에만 초기화 가능, 중간에 값을 변경할 수 없음. -> Java의 final
ex) runtime을 할 시 변경되지 말아야 할 값은 안전하게 val로 선언하는 것이 좋습니다.
◎ 변수는 '선언 위치' 따라 두가지 이름으로 불립니다.
- 클래스에 선언된 변수 : Property(속성)
- Scope 내에 선언된 변수 : Local Variable ( 로컬(지역) 변수 )
◎ 코틀린은 기본 변수에서 null을 허용하지 않습니다.
- 고전적인 언어들은, 변수가 선언된 후 초기화 되지 않으면
기본 값으로 초기화 되거나 값이 할당되지 않았다는 표시로 null 값을 가지게 됩니다.
- 코틀린은 기본 변수에서 null을 허용하지 않고,
+ 변수에 값을 할당하지 않은채로 사용하게 되면 문법 에러를 표시하고
++ 컴파일을 막아주므로
의도치 않은 코드의 동작이나 'null point exception' 등을 원천적으로 차단해준다는 장점이 있습니다.
fun main() {
var a: Int = 123 //코틀린은 값 초기화 필수!
println(a)
println(main2())
}
+ 변수에 값을 할당하는 것은 반드시 선언시에 할 필요는 없으며,
변수를 참조하여 사용하기 전까지만 하면 됩니다.
fun main2() {
var b: Int
b = 123 //이렇게 초기화해도 된다
println(b)
}
++ 변수에 값이 할당되지 않았다는 것을 하나의 정보로 사용하는 경우도 있음. ( ? 활용 )
fun main() {
var a:Int? = null
}
- > null을 허용하는 'nullable 변수' 로 선언 가능합니다.
하지만, ' null pointer exception ' 발생할 수 있으므로 꼭 필요한 경우에 한해서 주의해서 사용해야합니다.
Ⅱ. 자료형.
- 변수에서 사용할 수 있도록, 코틀린이 제공하는 기본 자료형은 자바와의 호환을 위해 ' 자바와 거의 동일 ' 합니다.
☆ 정수, 실수형.
fun main() {
var intValue:Int = 1234
var longValue:Long = 1234L //L을 붙여 더 큰 메모리를 사용하는 정수임을 표시
var intValueByHex:Int = 0x1af //16진수
var intValueByBin:Int = 0b //2진수 (binary 약자)
//코틀린은 8진수 표기는 지원하지 않는다.
var doubleValue:Double = 123.5 //실수는 소수점을 포함해 숫자를 쓰거나
var doubleValueWithExp:Double = 123.5e10 //필요시 지수 표기법을 추가한다.
var floatValue:Float = 123.5f //Float는 f를 붙인다.
}
- > 코틀린은 내부적으로 문자열을 UTF-16 BE 방식을 사용합니다.
- > 따라서, 글자 하나하나 2byte의 메모리 공간을 사용합니다.
☆ 문자, 문자열.
fun main() {
var charValue:Char = 'a'
var koreanCharValue:Char = '가'
var stringValue = "one line string test"
var multiLineStringValue = """multiline
string
test"""
}
☆ 불리언값.
fun main() {
var booleanValue:Boolean = true
}
Ⅲ. 형 변환.
※ 코틀린은 형-변환시 발생할 수 있는 오류를 막기위해서,
다른 언어들이 지원하는 '암시적 형변환'은 지원하지 않습니다.
○ 명시적 형변환 : 변환될 자료형을 개발자가 직접 지정.
○ 암시적 형변환 : 변수를 할당할 시 자료형을 지정하지 않아도 자동으로 형변환 됩니다.
※기본타입 형-변환 함수.
val intValue: Int = 10
val longValue: Long = intValue.toLong()
val doubleValue: Double = 3.14
val floatValue: Float = doubleValue.toFloat()
val stringValue: String = "100"
val parsedInt: Int = stringValue.toInt()
package com.example.testapplication.test
fun main() {
var a: Int = 54321
var b: Long = a.toLong() //int를 long형으로 변환
println(a)
println(b)
typeCheck(a)
typeCheck(b)
}
fun typeCheck(obj:Any):Int?{ //Any는 모든 타입의 부모격이다
//is 키워드는 객체 타입을 체크합니다.
if(obj is String){
println("String 입니다.")
}else if(obj is Int){
println("Int 입니다.")
}else {
println("그 이외의 타입입니다.")
}
return null
}
※문자열 형-변환 함수.
: 문자열을 숫자 타입으로 변환할 때는 다음과 같은 함수들을 활용.
-변환 실패 시 null값을 반환하므로, 안전한 형-변환이 가능합니다.
val str = "100"
val number = str.toIntOrNull() ?: 0
※객체 형변환
: 객체의 형변환에는 'as' 키워드를 사용합니다.
val obj: Any = "Hello"
val str: String = obj as String
+ 안전한 형변환을 위해서 'as?' 를 사용할 수도 있습니다.
※스마트 캐스트.
: 타입 검사 후 자동으로 형변환이 이루어집니다.
val obj: Any = "Hello"
if (obj is String) {
println(obj.length) // obj가 자동으로 String으로 캐스팅됨
}
Ⅳ. 배열.
※ 코틀린의 배열은 고정된 크기를 가지고 있는 데이터 구조로,
동일한 타입의 요소들을 순차적으로 저장합니다.
[ == 한번 선언하고 나면, 전체 크기를 변경할 수 없다는 단점이 있지만,
한번 선언하면 다른 자료구조보다 빠른 입출력이 가능해진다는 장점 ! ]
∇ 배열 생성.
: 코틀린에서는 여러 가지 방법으로 배열을 생성 가능합니다.
1. arrayOf() 함수 사용. !
val numbers = arrayOf(1, 2, 3, 4, 5)
val mixedArray = arrayOf(1, "two", 3.0, true)
2. Array 생성자 사용. !
val squareNumbers = Array(5) { i -> i * i }
3. 특정 타입의 배열 생성
val intArray = IntArray(5)
val charArray = CharArray(3) { 'a' }
§ 배열 접근 및 수정.
val fruits = arrayOf("Apple", "Banana", "Cherry")
println(fruits[0]) // "Apple" 출력
fruits[1] = "Blueberry"
§ 배열 순회
val numbers = arrayOf(1, 2, 3, 4, 5)
// for 루프 사용
for (number in numbers) {
println(number)
}
// 인덱스를 사용한 순회
for (i in numbers.indices) {
println("Index $i: ${numbers[i]}")
}
// withIndex() 사용
for ((index, value) in numbers.withIndex()) {
println("Index $index: $value")
}
§ 유용한 배열 함수.
val numbers = arrayOf(1, 2, 3, 4, 5)
println(numbers.size) // 배열의 크기
println(numbers.sum()) // 모든 요소의 합
println(numbers.average()) // 평균값
println(numbers.max()) // 최대값
println(numbers.min()) // 최소값
§ 다차원 배열
val matrix = Array(3) { IntArray(3) }
package com.example.testapplication.test
fun main() {
// 1. arrayOf() 함수를 사용한 배열 생성
val numbers = arrayOf(1, 2, 3, 4, 5)
println("numbers: ${numbers.contentToString()}")
println("--------")
// 2. Array 생성자를 사용한 배열 생성
val squareNumbers = Array(5) { i -> i * i }
println("squareNumbers: ${squareNumbers.contentToString()}")
println("--------")
// 3. 특정 타입의 배열 생성
val intArray = IntArray(5) { it * 2 }
println("intArray: ${intArray.contentToString()}")
println("--------")
// 4. 문자 배열 생성
val charArray = CharArray(3) { 'a' + it }
println("charArray: ${charArray.contentToString()}")
println("--------")
// 5. 2차원 배열 생성 및 출력
val matrix = Array(3) { IntArray(3) { it } }
println("matrix:")
for (row in matrix) {
println(row.contentToString())
}
println("--------")
// 6. 배열 요소 접근 및 수정
val fruits = arrayOf("Apple", "Banana", "Cherry")
println("Original fruits: ${fruits.contentToString()}")
fruits[1] = "Blueberry"
println("Modified fruits: ${fruits.contentToString()}")
println("--------")
// 7. 배열 순회 및 출력
println("Fruits:")
for ((index, fruit) in fruits.withIndex()) {
println("Index $index: $fruit")
}
println("--------")
// 8. 배열 함수 사용
println("Sum of numbers: ${numbers.sum()}")
println("Average of numbers: ${numbers.average()}")
println("Max of numbers: ${numbers.max()}")
println("Min of numbers: ${numbers.min()}")
}
☆ 배열의 특징.
1. 코틀린의 배열은 불변(immutable)이 아닙니다. 요소의 값을 변경할 수 있습니다.
2. 배열의 크기는 생성 시점에 고정되며, 이후에 변경할 수 없습니다.
3. 코틀린은 기본 타입(int, long, Double 등)에 대한
특별한 배열 클래스(IntArray, LongArray, DoubleArray 등)를제공합니다.
이들은 자바의 기본 타입 배열과 동일하게 동작하여, 성능상 이점이 있음.
4. Array<T> 생성자를 사용하면, 람다식을 통해 초기값을 설정할 수 있습니다.
- 코틀린의 배열은 자바의 배열과 유사하지만, 더 안전하고 편리한 기능들을 제공합니다.
- 특히 코틀린의 컬렉션 함수들과 함께 사용하면 배열을 더욱 효과적으로 다룰 수 있습니다.
Ⅴ. 타입 추론.
※ 코틀린의 타입 추론(Type inference)은 변수나 함수의 타입을 명시적으로 선언하지 않더라도
컴파일러가 자동으로 타입을 추론하는 기능입니다.
[ 코드를 더 간결하게 만들어주면서도 정적-타입 언어의 안전성을 유지할 수 있도록 해줍니다.]
☆ 타입 추론의 주요 특징.
1. 변수 선언 시 타입 추론 :
val name = "John" // String으로 추론
val age = 30 // Int로 추론
val pi = 3.14 // Double로 추론
2. 함수 반환 타입 추론 :
fun add(a: Int, b: Int) = a + b // Int로 추론
3. 컬렉션의 타입 추론 :
val numbers = listOf(1, 2, 3) // List<Int>로 추론
val names = setOf("Alice", "Bob") // Set<String>으로 추론
4. 람다 표현식의 타입 추론 :
val sum = { x: Int, y: Int -> x + y } // (Int, Int) -> Int로 추론
☆ 타입 추론의 장점.
1. 코드 간결성 : 타입을 명시적으로 작성하지 않아도 되므로, 코드가 더 간결.
2. 가독성 향상 : 불필요한 타입 선언이 줄어들어서, 코드의 핵심 로직에 집중 가능.
3. 생산성 증강 : 타입을 일일히 명시하지 않아도 되므로, 개발 속도가 향상.
4. 유연성 : 타입이 변경되더라도 코드 수정이 최소화.
☆ 주의사항.
1. 명시적 타입 선언이 필요한 경우
: 때로는 명시적으로 타입을 선언하는 것이 코드의 의도를 더 명확히 할 수도 있음.
2. 복잡한 제네릭 타입
: 복잡한 제네릭 타입의 경우에는 컴파일러가 정확히 추론하지 못할 수 있으므로,
명시적 선언이 필요할 수 있습니다.
3. 가독성 고려
: 때로는 타입을 명시하는 것이 코드의 의도를 더 명확히 전달 가능합니다.
* 코틀린의 타입 추론은, 정적 타입 언어의 안정성을 유지하면서도 동적 타입 언어의 간결함을 제공합니다.
-> 이는 코드를 더 읽기 쉽고 유지보수하기 쉽도록 만들어줍니다.
Ⅵ. 함수.
※ 함수 : 특정한 동작을 하거나 원하는 결과값을 연산하는데 사용합니다.
※ 함수 정의
: 코틀린에서 함수는 'fun' 키워드를 사용하여 정의합니다.
fun functionName(parameter1: Type1, parameter2: Type2): ReturnType {
// 함수 본문
return result
}
fun main() {
println(add(5, 6, 7))
}
fun add(a: Int, b: Int, c:Int): Int {
return a + b + c
//리턴 발생 시 함수 중간이더라도 함수 종료
}
-.> 실행 결과 : 18
* 단일 표현식 함수로 위 코드를 변형하면, 변수에 결과값을 할당하듯 기술할 수 있도록 합니다.
fun main() {
println(add(5, 6, 7))
}
fun add(a: Int, b: Int, c: Int) = a + b + c
- 단일 표현식 함수는 반환형의 타입 추론이 가능하므로, 반환형을 생략 가능.
※ 함수의 주요 특징.
1. 반환 타입 추론 :
fun sum(a: Int, b: Int) = a + b
- 단일 표현식 함수의 경우, 반환 타입을 생략 가능 !
2. 기본 매개변수 :
fun greet(name: String = "Guest") = "Hello, $name!"
- 매개변수에 기본값을 지정할 수 있습니다.
3. 네임드 매개변수 :
fun createUser(name: String, age: Int) = User(name, age)
val user = createUser(age = 25, name = "John")
- 함수 호출 시 매개변수 이름을 명시할 수 있습니다.
4. 가변 인자 :
fun sum(vararg numbers: Int): Int = numbers.sum()
- 'vararg' 키워드를 사용하여, 가변 개수의 인자를 받을 수 있습니다.
5. 지역 함수 :
fun outer() {
fun inner() {
println("Inner function")
}
inner()
}
- 함수 내부에 다른 함수를 정의할 수 있습니다.
6. 확장 함수 :
fun String.double(): String = this.repeat(2)
- 기존 클래스에 새로운 함수를 추가할 수 있습니다.
7. 중위 함수 :
infix fun Int.plus(other: Int) = this + other
val result = 1 plus 2
- ' infix' 키워드를 사용하여, 중위 표기법으로 호출할 수 있는 함수를 정의할 수 있습니다.
8. 최상위 함수
: 코틀린에서는 함수를 클래스 외부에, 최상위 레벨로 정의 가능합니다.
9. 함수 타입
: 코틀린에서는 함수를 변수에 할당하거나, 다른 함수의 매개변수로 전달 가능합니다.
10. 최상위 함수
: 코틀린에서는 함수를 클래스 외부에, 최상위 레벨로 정의 가능합니다.
fun main() {
// 1. 기본 함수 정의와 호출
println("Sum: ${sum(5, 3)}")
// 2. 반환 타입 추론
println("Multiply: ${multiply(4, 7)}")
// 3. 기본 매개변수
greet()
greet("Alice")
// 4. 네임드 매개변수
createUser(age = 30, name = "Bob")
// 5. 가변 인자
println("Sum of numbers: ${sumAll(1, 2, 3, 4, 5)}")
// 6. 지역 함수
outerFunction()
// 7. 확장 함수
val str = "Hello"
println("Doubled string: ${str.double()}")
// 8. 중위 함수
println("Infix function result: ${5 plus 3}")
// 9. 함수 타입
val operation: (Int, Int) -> Int = ::sum
println("Function type result: ${operation(10, 20)}")
// 10. 꼬리 재귀 함수
println("Factorial of 5: ${factorial(5)}")
}
// 1. 기본 함수
fun sum(a: Int, b: Int): Int {
return a + b
}
// 2. 반환 타입 추론
fun multiply(a: Int, b: Int) = a * b
// 3. 기본 매개변수
fun greet(name: String = "Guest") {
println("Hello, $name!")
}
// 4. 네임드 매개변수
fun createUser(name: String, age: Int) {
println("Created user: $name, age: $age")
}
// 5. 가변 인자
fun sumAll(vararg numbers: Int): Int {
return numbers.sum()
}
// 6. 지역 함수
fun outerFunction() {
fun innerFunction() {
println("This is an inner function")
}
innerFunction()
}
// 7. 확장 함수
fun String.double(): String {
return this.repeat(2)
}
// 8. 중위 함수
infix fun Int.plus(other: Int): Int {
return this + other
}
// 9. 함수 타입 (이미 sum 함수로 정의됨)
// 10. 꼬리 재귀 함수
tailrec fun factorial(n: Int, accumulator: Int = 1): Int {
return when (n) {
0, 1 -> accumulator
else -> factorial(n - 1, n * accumulator)
}
}
'App_Dev > Android : Kotlin' 카테고리의 다른 글
[ 앱 개발자 도전기 : 안드로이드_코틀린 ] 안드로이드 빌드 과정(Android APK build Process)를 이해해보기. (0) | 2024.11.11 |
---|---|
[ 앱 개발자 도전기 : 안드로이드_코틀린 ] Kotlin 특징 - 코틀린이란?? 왜 쓰는걸까?? (0) | 2024.11.10 |