-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'Team-Sixteen-Study:main' into main
- Loading branch information
Showing
5 changed files
with
913 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.idea | ||
|
||
# Default ignored files | ||
/shelf/ | ||
/workspace.xml |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
236 changes: 236 additions & 0 deletions
236
jhwon91/8. ๊ณ ์ฐจ ํจ์: ํ๋ผ๋ฏธํฐ์ ๋ฐํ ๊ฐ์ผ๋ก ๋๋ค ์ฌ์ฉ.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
}) | ||
} | ||
``` | ||
|
||
|
||
|
||
|
||
|
Oops, something went wrong.