Skip to content

Commit

Permalink
Merge branch 'Team-Sixteen-Study:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Goryeojin authored Feb 3, 2025
2 parents 74d9236 + be439df commit 6b008d4
Show file tree
Hide file tree
Showing 5 changed files with 913 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.idea

# Default ignored files
/shelf/
/workspace.xml
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
# ๊ณ ์ฐจ ํ•จ์ˆ˜: ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ๋žŒ๋‹ค ์‚ฌ์šฉ
## 1. ๊ณ ์ฐจ ํ•จ์ˆ˜ ์ •์˜
- ๊ณ ์ฐจ ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ฑฐ๋‚˜ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋‹ค.
### ๐Ÿ“Œ ํ•จ์ˆ˜ ํƒ€์ž…
- ํ•จ์ˆ˜ ํƒ€์ž…์„ ์ •์˜ํ•˜๋ ค๋ฉด ํ•จ์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ํƒ€์ž…์„ ๊ด„ํ˜ธ ์•ˆ์— ๋„ฃ๊ณ , ๊ทธ ๋’ค์— ํ™”์‚ดํ‘œ(โ†’)๋ฅผ ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ, ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์ง€์ •ํ•˜๋ฉด ๋œ๋‹ค.
- ํ•จ์ˆ˜ ํƒ€์ž…์—์„œ๋„ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ๋„์ด ๋  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์œผ๋กœ ์ €์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
- ํ•จ์ˆ˜์˜ ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜ ํƒ€์ž… ์ „์ฒด๊ฐ€ ๋„์ด ๋  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์ž„์„ ์„ ์–ดํ•˜๊ธฐ ์œ„ํ•ด ํ•จ์ˆ˜ ํƒ€์ž…์„ ๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ๊ณ  ๊ทธ ๋’ค์— ๋ฌผ์Œํ‘œ๋ฅผ ๋ถ™์—ฌ์•ผ๋งŒ ํ•œ๋‹ค.
```kotlin
var canReturnNull: (Int, Int) -> Int? = {x, y -> null}
var funOrNull: ((Int, Int) -> Int) ? null
```

### ๐Ÿ“Œ ์ธ์ž๋กœ ๋ฐ›์€ ํ•จ์ˆ˜ ํ˜ธ์ถœ
```kotlin
fun twoAndThree(operation: (Int, Int) -> Int) {
val result = operation(2, 3)
println("The result is $result")
}

twoAndThree { a, b -> a + b } // The result is 5
twoAndThree { a, b -> a * b } // The result is 6
```
- ์ธ์ž๋กœ ๋ฐ›์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ๋ฌธ์€ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ๋ฌธ๊ณผ ๊ฐ™๋‹ค.
- ํ•จ์ˆ˜ ์ด๋ฆ„ ๋’ค์— ๊ด„ํ˜ธ๋ฅผ ๋ถ™์ด๊ณ  ๊ด„ํ˜ธ ์•ˆ์— ์›ํ•˜๋Š” ์ธ์ž๋ฅผ ์ฝค๋งˆ(,)๋กœ ๊ตฌ๋ถ„ํ•ด ๋„ฃ๋Š”๋‹ค
- String์— ๋Œ€ํ•œ filter๋ฅผ ๊ตฌํ˜„
- ๋ฌธ์ž์—ด์˜ ๊ฐ ๋ฌธ์ž๋ฅผ ์ˆ ์–ด์— ๋„˜๊ฒจ์„œ ๋ฐ˜ํ™˜ ๊ฐ’์ด true๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋‹ด๋Š” StringBuilder๋’ค์— ๊ทธ ๋ฌธ์ž๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
```kotlin
fun String.filter(predicate: (Char) -> Boolean): String {
val sb = StringBuilder()
for (index in 0 until length) {
val element = get(index)
if (predicate(element)) sb.append(element)
}
return sb.toString()
}

println("ab1c".filter { it in 'a'..'z' }) //abc
```


### ๐Ÿ“Œ ์ž๋ฐ”์—์„œ ์ฝ”ํ‹€๋ฆฐ ํ•จ์ˆ˜ ํƒ€์ž… ์‚ฌ์šฉ
- ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ ์•ˆ์—์„œ ํ•จ์ˆ˜ ํƒ€์ž…์€ ์ผ๋ฐ˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋ฐ”๋€๋‹ค.
- ํ•จ์ˆ˜ ํƒ€์ž…์˜ ๋ณ€์ˆ˜๋Š” FunctionN ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•œ๋‹ค.
- ์ฝ”ํ‹€๋ฆฐ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํ•จ์ˆ˜ ์ธ์ž์˜ ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ Function0(์ธ์ž๊ฐ€ ์—†๋Š” ํ•จ์ˆ˜), Function1<P1, R>(์ธ์ž๊ฐ€ ํ•˜๋‚˜์ธ ํ•จ์ˆ˜) ๋“ฑ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณต


### ๐Ÿ“Œ ๋””ํดํŠธ ๊ฐ’์„ ์ง€์ •ํ•œ ํ•จ์ˆ˜ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋‚˜ ๋„์ด ๋  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ
- ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ•จ์ˆ˜ ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•  ๋•Œ๋„ ๋””ํดํŠธ ๊ฐ’์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
```kotlin
fun <T> Collection<T>.joinToString(
separator: String = ", ",
prefix: String = "",
postfix: String = "",
transform: (T) -> String = { it.toString() } // ํ•จ์ˆ˜ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์„ ์–ธํ•˜๋ฉด์„œ ๋žŒ๋‹ค๋ฅผ ๋””ํดํŠธ ๊ฐ’์œผ๋กœ ์ง€์ •ํ•œ๋‹ค.
): String {
val result = StringBuilder(prefix)

for ((index, element) in this.withIndex()) {
if (index > 0) result.append(separator)
result.append(transform(element)) // "transform" ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
}

result.append(postfix)
return result.toString()
}

val letters = listOf("Alpha", "Beta")
println(letters.joinToString()) // ๋””ํดํŠธ ๋ณ€ํ™˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. -> Alpha, Beta
println(letters.joinToString { it.toLowerCase() }) // ๋žŒ๋‹ค๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌํ•œ๋‹ค. -> alpha, beta
println(letters.joinToString(separator = "! ", postfix = "! ",
transform = { it.toUpperCase() })) // ์ด๋ฆ„ ๋ถ™์€ ์ธ์ž ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด ๋žŒ๋‹ค๋ฅผ ํฌํ•จํ•˜๋Š” ์—ฌ๋Ÿฌ ์ธ์ž๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. -> ALPHA! BETA!
```


### ๐Ÿ“Œ ํ•จ์ˆ˜๋ฅผ ํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜
```kotlin
// ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ์ •์˜
enum class Delivery { STANDARD, EXPEDITED }

class Order(val itemCount: Int)

fun getShippingCostCalculator(
delivery: Delivery): (Order) -> Double { // ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•œ๋‹ค.
if (delivery == Delivery.EXPEDITED) {
return { order -> 6 + 2.1 * order.itemCount } //ํ•จ์ˆ˜์—์„œ ๋žŒ๋‹ค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
}

return { order -> 1.2 * order.itemCount } //ํ•จ์ˆ˜์—์„œ ๋žŒ๋‹ค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
}

val calculator = getShippingCostCalculator(Delivery.EXPEDITED) // ๋ฐ˜ํ™˜๋ฐ›์€ ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅํ•œ๋‹ค.
println("Shipping costs ${calculator(Order(3))}") // Shipping costs 12.3
```
- `getShippingCostCalculator` ํ•จ์ˆ˜๋Š” `Order`๋ฅผ ๋ฐ›์•„์„œ Double์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
- ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด return ์‹์— ๋žŒ๋‹ค๋‚˜ ๋ฉค๋ฒ„ ์ฐธ์กฐ๋‚˜ ํ•จ์ˆ˜ ํƒ€์ž…์˜ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋Š” ์‹ ๋“ฑ์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

### ๐Ÿ“Œ ๋žŒ๋‹ค๋ฅผ ํ™œ์šฉํ•œ ์ค‘๋ณต ์ œ๊ฑฐ
- ํ•จ์ˆ˜ ํƒ€์ž…๊ณผ ๋žŒ๋‹ค ์‹์€ ์žฌํ™œ์šฉํ•˜๊ธฐ ์ข‹์€ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ๋•Œ ์“ธ ์ˆ˜ ์žˆ๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ๋‹ค.
```kotlin
data class SiteVisit(
val path: String,
val duration: Double,
val os: OS
)

enum class OS { WINDOWS, LINUX, MAC, IOS, ANDROID }

val log = listOf(
SiteVisit("/", 34.0, OS.WINDOWS),
SiteVisit("/", 22.0, OS.MAC),
SiteVisit("/login", 12.0, OS.WINDOWS),
SiteVisit("/signup", 8.0, OS.IOS),
SiteVisit("/", 16.3, OS.ANDROID)
)

val averageWindowsDuration = log
.filter { it.os == OS.WINDOWS }
.map(SiteVisit::duration)
.average()

fun List<SiteVisit>.averageDurationFor(os: OS) =
filter { it.os == os }.map(SiteVisit::duration).average()

println(log.averageDurationFor(OS.WINDOWS)) // 23.0
println(log.averageDurationFor(OS.MAC)) // 22.0
```

```kotlin
//๊ณ ์ฐจ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ค‘๋ณต ์ œ๊ฑฐํ•˜๊ธฐ
fun List<SiteVisit>.averageDurationFor(predicate: (SiteVisit) -> Boolean) =
filter(predicate).map(SiteVisit::duration).average()

println(log.averageDurationFor {
it.os in setOf(OS.ANDROID, OS.IOS) }) // 12.15
println(log.averageDurationFor {
it.os == OS.IOS && it.path == "/signup" }) // 8.0
```

## 2. ์ธ๋ผ์ธ ํ•จ์ˆ˜: ๋žŒ๋‹ค์˜ ๋ถ€๊ฐ€ ๋น„์šฉ ์—†์• ๊ธฐ
- inline ๋ณ€๊ฒฝ์ž๋ฅผ ์–ด๋–ค ํ•จ์ˆ˜์— ๋ถ™์ด๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ทธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ชจ๋“  ๋ฌธ์žฅ์„ ํ•จ์ˆ˜ ๋ณธ๋ฌธ์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ๋ฐ”๊ฟ”์น˜๊ธฐ ํ•ด์ค€๋‹ค.
### ๐Ÿ“Œ ์ธ๋ผ์ด๋‹์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹
- ํ•จ์ˆ˜๋ฅผ inline์œผ๋กœ ์„ ์–ธํ•˜๋ฉด ๊ทธ ํ•จ์ˆ˜์˜ ๋ณธ๋ฌธ์ด ์ธ๋ผ์ธ๋œ๋‹ค.
- ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐ”์ดํŠธ์ฝ”๋“œ ๋Œ€์‹ ์— ํ•จ์ˆ˜ ๋ณธ๋ฌธ์„ ๋ฒˆ์—ญํ•œ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.
```kotlin
inline fun <T> synchronized(lock: Lock, action: () -> T): T {
lock.lock()
try {
return action()
}
finally {
lock.unlock()
}
}

val l = Lock()

synchronized(l) {
// ...
}
```
- synchronized ํ•จ์ˆ˜๋ฅผ inline์œผ๋กœ ์„ ์–ธํ–ˆ์œผ๋ฏ€๋กœ synchronized ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ๋Š” ๋ชจ๋‘ ์ž๋ฐ”์˜ synchronized ๋ฌธ๊ณผ ๊ฐ™์•„์ง„๋‹ค.

## 3. ๊ณ ์ฐจ ํ•จ์ˆ˜ ์•ˆ์—์„œ ํ๋ฆ„ ์ œ์–ด
### ๐Ÿ“Œ ๋žŒ๋‹ค์•ˆ์˜ return๋ฌธ: ๋žŒ๋‹ค๋ฅผ ๋‘˜๋Ÿฌ์‹ผ ํ•จ์ˆ˜๋กœ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜
- ๋‹ค์Œ ์ฝ”๋“œ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ด๋ฆ„์ด Alice์ธ ๊ฒฝ์šฐ์— lookForAlice ํ•จ์ˆ˜๋กœ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜๋œ๋‹ค.
```kotlin
data class Person(val name: String, val age: Int)

val people = listOf(Person("Alice", 29), Person("Bob", 31))

fun lookForAlice(people: List<Person>) {
for (person in people) {
if (person.name == "Alice") {
println("Found!")
return
}
}
println("Alice is not found")
}
```
- forEach ํ•จ์ˆ˜๋ฅผ ๋Œ€์‹  ์จ๋„ ์•ˆ์ „ํ•˜๋‹ค.
```kotlin
fun lookForAlice(people: List<Person>) {
people.forEach {
if (it.name == "Alice") {
println("Found!")
return
}
}
println("Alice is not found")
}
```
- ๋žŒ๋‹ค ์•ˆ์—์„œ return์„ ์‚ฌ์šฉํ•˜๋ฉด ๋žŒ๋‹ค๋กœ๋ถ€ํ„ฐ๋งŒ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๊ทธ ๋žŒ๋‹ค๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰์„ ๋๋‚ด๊ณ  ๋ฐ˜ํ™˜๋œ๋‹ค.
- ์ž์‹ ์„ ๋‘˜๋Ÿฌ์‹ธ๊ณ  ์žˆ๋Š” ๋ธ”๋ก๋ณด๋‹ค ๋” ๋ฐ”๊นฅ์— ์žˆ๋Š” ๋‹ค๋ฅธ ๋ธ”๋ก์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” return ๋ฌธ์„ ๋„Œ๋กœ์ปฌ(non-local) return์ด๋ผ ๋ถ€๋ฅธ๋‹ค.
- return์ด ๋ฐ”๊นฅ์ชฝ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๋•Œ๋Š” ๋žŒ๋‹ค๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜๊ฐ€ ์ธ๋ผ์ธ ํ•จ์ˆ˜์ธ ๊ฒฝ์šฐ๋ฟ์ด๋‹ค.


### ๐Ÿ“Œ ๋žŒ๋‹ค๋กœ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜: ๋ ˆ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ return
- ๋žŒ๋‹ค ์‹์—์„œ๋„ ๋กœ์ปฌ return์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋žŒ๋‹ค ์•ˆ์—์„œ ๋กœ์ปฌ return์€ for๋ฃจํ”„์˜ break์™€ ๋น„์Šทํ•œ ์—ญํ• ์„ ํ•œ๋‹ค.
- ๋กœ์ปฌ return๊ณผ ๋„Œ๋กœ์ปฌ return์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ๋ ˆ์ด๋ธ”(label)์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
```kotlin
//๋ ˆ์ด๋ธ”์„ ํ†ตํ•ด ๋กœ์ปฌ ๋ฆฌํ„ด ์‚ฌ์šฉํ•˜๊ธฐ
fun lookForAlice(people: List<Person>) {
people.forEach label@{ //๋žŒ๋‹ค์‹ ์•ž์— ๋ ˆ์ด๋ธ”์„ ๋ถ™์ธ๋‹ค.
if (it.name == "Alice") return@label //return@label์€ ์•ž์—์„œ ์ •์˜ํ•œ ๋ ˆ์ด๋ธ”์„ ์ฐธ์กฐํ•œ๋‹ค.
}
println("Alice might be somewhere") //ํ•ญ์ƒ ์ด์ค„์ด ์ถœ๋ ฅ๋œ๋‹ค.
}
```
- ๋žŒ๋‹ค์— ๋ ˆ์ด๋ธ”์„ ๋ถ™์—ฌ์„œ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ๋žŒ๋‹ค๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š” ์ธ๋ผ์ธ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์„ return ๋’ค์— ๋ ˆ์ด๋ธ”๋กœ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค.
```kotlin
fun lookForAlice(people: List<Person>) {
people.forEach {
if (it.name == "Alice") return@forEach
}
println("Alice might be somewhere")
}
```
- ๋žŒ๋‹ค ์‹์˜ ๋ ˆ์ด๋ธ”์„ ๋ช…์‹œํ•˜๋ฉด ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๋ ˆ์ด๋ธ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.


### ๐Ÿ“Œ ๋ฌด๋ช… ํ•จ์ˆ˜: ๊ธฐ๋ณธ์ ์œผ๋กœ ๋กœ์ปฌ return
- ๋ฌด๋ช… ํ•จ์ˆ˜๋Š” ์ฝ”๋“œ ๋ธ”๋ก์„ ํ•จ์ˆ˜์— ๋„˜๊ธธ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด๋‹ค.
```kotlin
fun lookForAlice(people: List<Person>) {
people.forEach(fun (person) { //๋žŒ๋‹ค ์‹ ๋Œ€์‹  ๋ฌด๋ช… ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
if (person.name == "Alice") return // return ์€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฅดํ‚ค๋Š”๋ฐ ์ด ์œ„์น˜์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํ•จ์ˆ˜๋Š” ๋ฌด๋ช… ํ•จ์ˆ˜๋‹ค.
println("${person.name} is not Alice")
})
}
```





Loading

0 comments on commit 6b008d4

Please sign in to comment.