와챠의 우당탕탕 코딩 일기장
[Android/Kotlin]Udemy 강의 정리: Kotlin Basics(1) 본문
목차
- """ """: Triple-quoted
- Array 종류
- complier / complie time / run time
- !!: not-null assertion operator
- Type Check
- loop-break
- data class
- Module
- visiblilty modifier(가시성 변경자): package, class member
- Collections(List, Set, Map)
- 데이터 가져오기
- 조건으로 값 반환하기
- Map
- joinToString
- Filtering
- Partition
- Grouping
1. Triple-quoted
Triple-quoted를 사용하면 \n이나 \$를 하지 않아도 줄바꾸기, 특수문자 인식 가능
val text = """
그냥 이렇게
아무무렇게나 쓰면 됨
""".trimIndent()
2. Array
String 형식이 아닌 배열은 primitive type arrays라고 함(IntArray, ShortArray, FloatArray 등)
선언 방식은 아래 3가지가 있다
val numbers = intArrayOf(2, 5, 8, 12) // type명이 붙은 array에 바로 초기화
val intArray = IntArray(3) // Size만 지정
val floatArray = FloatArray(5) { -1f } // 배열의 size와 초기값 지정
3.
Compiler
- 프로그래밍 언어로 작성한 소스코드 ------- 컴파일러------> 기계어로 번역
- 소스코드 ------빌드-----> output
Compile time
- 컴파일 시 요구되는 시간
- 기계어로 번역되는 과정
- 컴파일 타임 오류 유형: Type check error, Syntax error
Run time
- 컴파일이 끝난 뒤 프로그램이 실행되는 시간
- 런타임 오류 유형: 0 나누기 오류, Null 참조 오류, 메모리 부족 오류
4. not-null assertion operator(!!)
!! : not-null assertion operator
!!을 사용을 줄이도록 노력해야겠단 생각이 들었다.
NullPointerException 오류를 조금이라도 더 줄이기 위해!!
그동안은 그냥 빨간 줄 생기고 내 눈으로 봤을 때 그 변수가 null이 아니라고 생각되면 !!처리 했었는데
주의해야겠다!! !!<쓰지 않아도 작동되도록!!
예를들면 if (userName.isEmpty()) 애서 빨간 줄 뜨면 무작정 !!처리 하지 말고
.isNullOrEmpty()를 해본다든가 if (userName.isEmpty() == true) 로 해본다든가 등등,,,
5. Type Check
type 체크 시 is 사용
type 검사 이후에는 해당 type로 자동 변환됨
when (x) {
is Int -> print(x + 1)
is String -> print(x)
...
}
아레 두 코드는 같은 코드...먼가 나도 나중에 실수할 거 같아서 올림
val text1: String? = x as? String
val text2: String? = x as String?
6. loop - break
val arr = arrayOf(
intArray(1, 2, 3),
intArray(4, 5, 6)
)
loop@ for (row in arr)
for (col in row)
if (col == 2) break@loop
break는 가장 가까운 loop를 종료시키는데
label을 달면 실행 지점을 label로 이동시킬 수 있다.
continue도 마찬가지
7. data class
class 생성 시 toString, eqauls, hashSetOf를 override 해주어야하는데
kotlin은 data class가 기본적인 걸 다 해줌
8. Module
: 한번에 컴파일되는 묶음
위 사진은 shoppie-kotlin-console-app 모듈 하위에
consoleApp 모듈, library 모듈에 각각 kotlin 파일 나눈 것
왜 모듈별로 나누냐면:
기능별로 나누고 싶다거나, 구현의 관심사가 다른 경우를 모듈로 반영할 수 있기 때문
가시성도 좋아짐
9. visiblity modifier(가시성 변경자): package, class member
visibility modifier(가시성 변경자): package
modifier | scope |
public | defult, 어느 위치에서든 참조 가능 |
private | 선언한 file 내부에서만 참조 가능 |
internal | 같은 module 안에서만 참조 가능 |
protected | x |
visibility modifier(가시성 변경자): class member
modifier | scope |
public | defult, 어느 위치에서든 참조 가능 |
private | 선언한 class 내부에서만 참조 가능 |
internal | 같은 module 안에서만 참조 가능 |
protected | 선언한 class + subclass에서는 참조 가능 |
코틀린 접하면서 단 한번도 가시성 변경자 사용해 본 적 없음,,,항상 기본만 써봄
근데 이렇게 배우니 괜히 한 번 써보고 싶음
10. Collections(List, Set, Map)
List는 순서대로 저장되는 배열
Set은 중복없이 저장되는 배열
Map은 key-value로 저장되는 배열
mapOf("first" to 1, "secont" to 2) 이런 식으로 만든다.
동일한 key의 값은 하나만 저장됨!!!
하지만 위는 모두 read-only라서 수정 불가, 추가된 값만 읽을 수 있음
수정하려면 그 아래 Mutable 붙은 거 사용해야 함!
10-1. Collection: 데이터 가져오기
elementAt / elementAtOrNull / elementAtOrElse / firstOrNull / lastOrNull
// 위치로 값 반환하기
val list = arrayOf(1, 2, 3, 4, 5)
println("${list.elementAt(0)}") // 맨 처음 원소 리턴
println("${list.elementAtOrNull(5)}") // 5번쨰 원소 있으면 반환 없으면 null 반환
println("${list.elementAtOrElse(5) { -1 } }") // 5번째 원소 있으면 반환 없으면 -1 반환
// 맨 처음 원소 반환, 없으면 null 반환
println("${list.first()}, ${list.firstOrNull()}")
// 맨 마지막 원소 반환, 없으면 null 반환
println("${list.last()}, ${list.lasttOrNull()}")
10-2. Collection: 조건으로 값 반환하기
// 조건으로 값 반환하기
// list(it)의 값이 3보다 큰 첫 번째 원소 출력, 없으면 null 반환
println("${list.firstOfNull { it > 3 } }")
println("${list.find { it > 3 } }") // 위와 같음
// 마지막부터 순서대로 확인하는 거는
// lastOrNull
// findLast
10-3. Collection: Map
// Map
val numbers = setOf(1, 2, 3)
// it = numbers의 원소
// 원소 * 3 출력
println(numbers.map{ it * 3 }) // {3, 6, 9}
// index * 원소 출력
println(numbers.mapIndexed { idx, value -> value * idx } ) // {0, 2, 6}
// 0*1 = 0, 1*2 = 2, 2*3 = 6
10-4. Collection: joinToString
val numbers = arrayOF("one", "two", "three")
println(numbers.joinToString(
separator = "|",
prefix = "start: ",
postfix = ": end"
))
// start: one | two | three : end
10-5. Collection: Filtering
// 필터링
val numbers = arrayOf("one", "two", "three", "four")
// 문자 길이 3 이상
val longerThen3 = numbers.filter { it.length > 3 }
// 조건맞는 원소 하나라도 있으면 true 반환
println(numbers.any { it.endsWith("e") } ) // true
// 조건맞는 원소 하나도 없으면 true 반환
println(numbers.none { it.endsWith("a") } ) // true
// 모든 원소가 조건 만족해야 true
println(numbers.all { it.endsWith("e") } ) // false
10-6. Collection: Partition
// 파티션
// 조건 만족하는 원소랑 아닌 원소 나누기
val numbers = arrayOf("one", "two", "three", "four")
// 원소 길이가 3보다 큰지?
val (match, rest) = numbers.partition{ it.lenth > 3 }
10-7. Collection: Grouping
// 그루핑(Grouping)
// groupBy: 지정된 기준값을 key로 한 Map 타입으로 변경
data class Product(val categoryLabel: String, val name: String)
private val products = arrayOf(
Product("패션", "겨울바지"),
Product("패션", "가을 바지"),
Product("전자기기", "핸드폰"),
Product("전자기기", "블루투스 이어폰"),
Product("전자기기", "노트북"),
Product("반려동물물품", "건식사료"),
Product("반려동물물품", "습식사료"),
Product("반려동물물품", "치약"),
Product("반려동물물품", "간식")
)
// 카테고리 이름(categoryLabel)을 key로, 카테고리 목록을 value로 하여 Map을 만듦
private val categories: Map<String, List<Product>> = products.groupBy { products->
products.categoryLabel
}
결과: