728x90

๊ฐœ๋ฐœ 32

[Kotlin in action] 6. ์ฝ”ํ‹€๋ฆฐ ํƒ€์ž… ์‹œ์Šคํ…œ

#1. null ๊ฐ€๋Šฅ์„ฑ (nullability) NPE๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋•๊ธฐ ์œ„ํ•œ ์ฝ”ํ‹€๋ฆฐ ํƒ€์ž… ์‹œ์Šคํ…œ์˜ ํŠน์„ฑ Nullable ํƒ€์ž… ์ฝ”ํ‹€๋ฆฐ ํƒ€์ž… ์‹œ์Šคํ…œ์ด null์ด ๋  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์›ํ•œ๋‹ค. ํƒ€์ž… ์ด๋ฆ„ ๋’ค์— ?๋ฅผ ๋ถ™์ด๋ฉด ๊ทธ ํƒ€์ž…์˜ ๋ณ€์ˆ˜๋‚˜ ํ”„๋กœํผํ‹ฐ์— null ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ?๊ฐ€ ์—†๋Š” ํƒ€์ž…์€ ๊ทธ ๋ณ€์ˆ˜๊ฐ€ null ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์—†๋‹ค. Nullable ํƒ€์ž…์ธ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด ๋ณ€์ˆ˜.๋ฉ”์„œ๋“œ() ์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•  ์ˆ˜๋Š” ์—†๋‹ค. Nullable ๊ฐ’์„ NonNull ํƒ€์ž…์˜ ๋ณ€์ˆ˜์— ๋Œ€์ž…ํ•  ์ˆ˜ ์—†๋‹ค. val x: String? = null val y: String = x //=> Error: Type mismatch: inferred type is String? but String was ex..

[Ktor] 3. Response

Ktor Client ๊ฐ€์ด๋“œ ์š”์•ฝ ์ •๋ฆฌ Ktor Documents ๊ธฐ์ค€ ๋ฒ„์ „: 1.6.2 ์‹œ๋ฆฌ์ฆˆ 1. ํด๋ผ์ด์–ธํŠธ, Engine 2. Request 3. Response Request๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ชจ๋“  ํ•จ์ˆ˜(request, get, post, …)๋Š” HttpResponse ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. Response body Raw body String val httpResponse: HttpResponse = client.get("https://ktor.io/") val stringBody: String = httpResponse.receive() ByteArray val httpResponse: HttpResponse = client.get("https://ktor.io/") val byteArrayBody: By..

[Ktor] 2. Request

Ktor Client ๊ฐ€์ด๋“œ ์š”์•ฝ ์ •๋ฆฌ Ktor Documents ๊ธฐ์ค€ ๋ฒ„์ „: 1.6.2 ์‹œ๋ฆฌ์ฆˆ 1. ํด๋ผ์ด์–ธํŠธ, Engine 2. Request 3. Response HttpClient์˜ request ํ•จ์ˆ˜๋กœ HTTP Request๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. request ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜ - ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ inline suspend fun HttpClient.request(urlString: String, block: HttpRequestBuilder.() -> Unit = {}): T inline suspend fun HttpClient.request(builder: HttpRequestBuilder = HttpRequestBuilder()): T ์ด์™ธ ๋ชจ๋“  ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋Š” ์—ฌ๊ธฐ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. Http..

[Ktor] 1. ํด๋ผ์ด์–ธํŠธ, Engine

Ktor Client ๊ฐ€์ด๋“œ ์š”์•ฝ ์ •๋ฆฌ Ktor Documents ๊ธฐ์ค€ ๋ฒ„์ „: 1.6.2 ์‹œ๋ฆฌ์ฆˆ 1. ํด๋ผ์ด์–ธํŠธ, Engine 2. Request 3. Response Engine Ktor HTTP ํด๋ผ์ด์–ธํŠธ๋Š” JVM, Android, JS, Native(iOS/desktop)๊ณผ ๊ฐ™์ด ๋‹ค๋ฅธ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ํŠน์ • ํ”Œ๋žซํผ์—์„œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ • engine์ด ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Android์—์„œ๋Š” OkHttp๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  JVM์—์„œ๋Š” Apache๋‚˜ CIO๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ktor-client-core ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์™ธ์— ๊ฐ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉํ•  engine์— ๋Œ€ํ•œ ๋””ํŽœ๋˜์‹œ๋Š” ๋ณ„๋„๋กœ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ ํ•œ๋‹ค. Engine dependency ๊ฐ€์ด๋“œ์—์„œ ํ”Œ๋žซํผ ๋ณ„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ engi..

[Kotlin In Action] 5. ๋žŒ๋‹ค๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๋žŒ๋‹ค์‹/๋žŒ๋‹ค: ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ๋„˜๊ธธ ์ˆ˜ ์žˆ๋Š” ์ž‘์€ ์ฝ”๋“œ ์กฐ๊ฐ #1. ๋žŒ๋‹ค์‹๊ณผ ๋ฉค๋ฒ„ ์ฐธ์กฐ ๋žŒ๋‹ค: ์ฝ”๋“œ ๋ธ”๋Ÿญ์„ ํ•จ์ˆ˜ ์ธ์ž๋กœ ๋„˜๊ธฐ๊ธฐ ๋žŒ๋‹ค ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ํ•„์š”๊ฐ€ ์—†๊ณ , ์ฝ”๋“œ ๋ธ”๋Ÿญ์„ ์ง์ ‘ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. button.setOnClickListener { /* actions on click */ } -> ๋žŒ๋‹ค๋ฅผ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•˜๋‚˜๋ฟ์ธ ๋ฌด๋ช… ๊ฐ์ฒด ๋Œ€์‹  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋žŒ๋‹ค์™€ ์ปฌ๋ ‰์…˜ ์˜ˆ์‹œ) maxBy: ์ปฌ๋ ‰์…˜์—์„œ ํŠน์ • ์กฐ๊ฑด์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์žฅ ํฐ ์›์†Œ๋ฅผ ์ฐพ์•„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ val people = listOf(Person("Alice", 29), Person("Bob", 31)) println(people.maxBy { it.age }) //๋น„๊ต์˜ ๊ธฐ์ค€์ด ๋  ๊ฐ’์„ ๋žŒ๋‹ค๋กœ ์ „๋‹ฌํ•œ๋‹ค. ํ•จ์ˆ˜๋‚˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ..

[Android Studio] MacOS Big Sur 11.3์—์„œ ์•ˆ๋“œ๋กœ์ด๋“œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์„ ๋•Œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

์ตœ๊ทผ MacOS๋ฅผ Big Sur๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ณ ๋‚˜์„œ ์•ˆ๋“œ๋กœ์ด๋“œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ์ฐพ์•„๋ณด๋‹ˆ Android emulator ์ตœ์‹  ๋ฒ„์ „์—์„œ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ์—…๋ฐ์ดํŠธ ํ›„์—๋„ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์•„ ์•„๋ž˜ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ–ˆ๋‹ค. ์›์ธ์€ ์• ํ”Œ์ด hypervisor entitlement(๊ถŒํ•œ ๊ด€๋ จ?)๋ฅผ 'com.apple.vm.hypervisor'์—์„œ 'com.apple.security.hypervisor'๋กœ ๋ณ€๊ฒฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ํ•œ๋‹ค. 1. entitlements.xml ํŒŒ์ผ ์ƒ์„ฑ com.apple.security.hypervisor 2. ํ„ฐ๋ฏธ๋„์—์„œ ์•„๋ž˜ ์ปค๋งจ๋“œ ์‹คํ–‰ codesign -s - --entitlements entitlements.xml --force ~/Library/Andro..

[Kotlin In Action] 4. ํด๋ž˜์Šค, ๊ฐ์ฒด, ์ธํ„ฐํŽ˜์ด์Šค

#1. ํด๋ž˜์Šค ๊ณ„์ธต ์ •์˜ ์ธํ„ฐํŽ˜์ด์Šค ์ฝ”ํ‹€๋ฆฐ ์ธํ„ฐํŽ˜์ด์Šค ์•ˆ์—๋Š” ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฟ ์•„๋‹ˆ๋ผ ๊ตฌํ˜„์ด ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ƒํƒœ(ํ•„๋“œ)๋Š” ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†๋‹ค. //์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ interface Clickable { fun click() } //์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„ class Button : Clickable { //์ฝ”ํ‹€๋ฆฐ์€ ํด๋ž˜์Šค ํ™•์žฅ๊ณผ ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„ ๋ชจ๋‘ ์ฝœ๋ก (:)์„ ๋ถ™์ธ๋‹ค. //์˜ค๋ฒ„๋ผ์ด๋“œ ํ‘œ์‹œ override fun click() = println("I was clicked") } ์ž๋ฐ”์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ฐœ์ˆ˜ ์ œํ•œ์—†์ด ๋งˆ์Œ๋Œ€๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํด๋ž˜์Šค๋Š” ์˜ค์ง ํ•˜๋‚˜๋งŒ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ์ƒ์œ„ ํด๋ž˜์Šค์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ์™€ ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์šฐ์—ฐํžˆ ํ•˜์œ„ ํด๋ž˜์Šค์— ์„ ์–ธํ•˜๋Š” ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ์ด ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์—..

[Kotlin In Action] 3. ํ•จ์ˆ˜ ์ •์˜์™€ ํ˜ธ์ถœ

#1. ํ•จ์ˆ˜ ํ˜ธ์ถœ fun joinToString( collection: Collection, separator: String, prefix: String, postfix: String ): String { val result = StringBuilder(prefix) for ((index, element) in collection.withIndex()) { if (index > 0) result.append(separator) result.append(element) } result.append(postfix) return result.toString() } ์ด๋ฆ„ ๋ถ™์ธ ์ธ์ž ์ž๋ฐ” joinToString(collection, /* separator */ " ", /* prefix */ " ", /* pos..

[Kotlin In Action] 2. ์ฝ”ํ‹€๋ฆฐ ๊ธฐ์ดˆ

#1. ํ•จ์ˆ˜ Hello, world! fun main(args: Array) { println("Hello, world!") } ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ fun ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ๋‚˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„ ๋’ค์— ํƒ€์ž…์„ ์“ด๋‹ค. ํ•จ์ˆ˜๋ฅผ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์— ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ํด๋ž˜์Šค ์•ˆ์— ๋„ฃ์–ด์•ผ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋ฐฐ์—ด๋„ ์ผ๋ฐ˜์ ์ธ ํด๋ž˜์Šค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค. ์„ธ๋ฏธ์ฝœ๋ก (;)์„ ๋ถ™์ด์ง€ ์•Š์•„๋„ ๋œ๋‹ค. statement(๋ฌธ)๊ณผ expression(์‹)์˜ ๊ตฌ๋ถ„ ์‹: ๊ฐ’์„ ๋งŒ๋“ค์–ด๋‚ด๋ฉฐ, ๋‹ค๋ฅธ ์‹์˜ ํ•˜์œ„์š”์†Œ๋กœ ๊ณ„์‚ฐ์— ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฌธ: ์ž์‹ ์„ ๋‘˜๋Ÿฌ์‹ธ๊ณ  ์žˆ๋Š” ๊ฐ€์žฅ ์•ˆ์ชฝ ๋ธ”๋Ÿญ์˜ ์ตœ์ƒ์œ„ ์š”์†Œ๋กœ ์กด์žฌํ•˜์—ฌ ์•„๋ฌด๋Ÿฐ ๊ฐ’์„ ๋งŒ๋“ค์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค. ์ž๋ฐ”์—์„œ๋Š” ๋ชจ๋“  ์ œ์–ด๊ตฌ์กฐ๊ฐ€ '๋ฌธ'์ธ ๋ฐ˜๋ฉด, ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ๋ฃจํ”„๋ฅผ ์ œ์™ธํ•œ ๋Œ€๋ถ€๋ถ„์˜ ์ œ์–ด๊ตฌ์กฐ๊ฐ€ '์‹'์ด๋‹ค. ์‹์ด..

[Kotlin In Action] 1. ์ฝ”ํ‹€๋ฆฐ์ด๋ž€ ๋ฌด์—‡์ด๋ฉฐ, ์™œ ํ•„์š”ํ•œ๊ฐ€?

#1. ์ฝ”ํ‹€๋ฆฐ(Kotlin)? ์ž๋ฐ” ํ”Œ๋žซํผ์—์„œ ๋Œ์•„๊ฐ€๋Š” ์ƒˆ๋กœ์šด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๊ฐ„๊ฒฐ, ์‹ค์šฉ์ , ์ž๋ฐ” ์ฝ”๋“œ์™€์˜ ์ƒํ˜ธ์šด์šฉ์„ฑ ์ค‘์‹œ #2. ์ฃผ์š” ํŠน์„ฑ ๋Œ€์ƒ ํ”Œ๋žซํผ ์„œ๋ฒ„, ์•ˆ๋“œ๋กœ์ด๋“œ ๋“ฑ ์ž๋ฐ”๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋ชจ๋“  ๊ณณ ์ •์  ํƒ€์ž… ์ง€์ • ์–ธ์–ด - ์ •์  ํƒ€์ž… ์ง€์ • ์–ธ์–ด: ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์„ฑ ์š”์†Œ์˜ ํƒ€์ž…์„ ์ปดํŒŒ์ผ ์‹œ์ ์— ์•Œ ์ˆ˜ ์žˆ๊ณ , ํ•„๋“œ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํƒ€์ž…์„ ๊ฒ€์ฆํ•ด์ค€๋‹ค. - ๋™์  ํƒ€์ž… ์ง€์ • ์–ธ์–ด: ํƒ€์ž…๊ณผ ๊ด€๊ณ„์—†์ด ๋ชจ๋“  ๊ฐ’์„ ๋ณ€์ˆ˜์— ๋„ฃ์„ ์ˆ˜ ์žˆ๊ณ , ํ•„๋“œ๋‚˜ ๋ฉ”์„œ๋“œ ์ ‘๊ทผ์— ๋Œ€ํ•œ ๊ฒ€์ฆ์ด ์‹คํ–‰ ์‹œ์ ์— ์ผ์–ด๋‚œ๋‹ค. ์ •์  ํƒ€์ž… ์ง€์ •์˜ ์žฅ์  ์„ฑ๋Šฅ: ์‹คํ–‰ ์‹œ์ ์— ์–ด๋–ค ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ• ์ง€ ์•Œ์•„๋‚ด๋Š” ๊ณผ์ •์ด ํ•„์š”์—†์–ด์„œ ๋น ๋ฅด๋‹ค. ์‹ ๋ขฐ์„ฑ: ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒ€์ฆํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹คํ–‰ ์‹œ ์˜ค๋ฅ˜๋กœ ์ค‘๋œ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์ ๋‹ค. ์œ ์ง€ ๋ณด์ˆ˜์„ฑ: ์ฝ”๋“œ์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฐ..