์ž ์ด ๊นจ์„œ ์ƒˆ๋ฒฝ์— ํฌ์ŠคํŒ…ํ•˜๊ธฐ๋Š” ์ •๋ง ์˜ค๋žœ๋งŒ์ด๋„ค์š”

์ด๋ฒˆ์—๋Š” ์ฝ”ํ‹€๋ฆฐ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค.

 

์ฝ”ํ‹€๋ฆฐ์—์„œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ๋ฒ•๋“ค

1. ํด๋ž˜์Šค ๋งŒ๋“ค๊ธฐ

data class Customer(val name: String, val email: String)

์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ์ด ํ•œ์ค„์ด๋ฉด ๊ฐ„๋‹จํžˆ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ์•„๋ž˜ ๋ฉ”์„œ๋“œ๋“ค์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

- getters, setters

- equals()

- hashCode()

- toString()

- copy() <-- ์ž๋ฐ”์˜ clone๊ณผ ๊ฐ™์€ ๋…€์„

- component1(), component2(), ... <--์ด๊ฑด ๋‚˜์ค‘์— ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋ณด๊ฒŒ๋  ๋•Œ ์•Œ๊ฒŒ๋  ๊ฒƒ ๊ฐ™๋„ค์š”

 

2. ํ•จ์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ธฐ๋ณธ ๊ฐ’ ์„ค์ •

ํ•จ์ˆ˜ ์ •์˜ ์‹œ ์ „๋‹ฌ๋ฐ›์„ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ธฐ๋ณธ๊ฐ’์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

fun foo(a: Int = 0, b: String = "") { ... }

์œ„ ์ฝ”๋“œ๋Š” foo ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ Int ํƒ€์ž…๊ณผ String ํƒ€์ž…์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ 0๊ณผ ๋นˆ ์ŠคํŠธ๋ง ""์„ ์ด์šฉํ•˜์—ฌ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ foo()๋ผ๊ณ  ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

3. ๋ฆฌ์ŠคํŠธ ํ•„ํ„ฐ๋ง

val positives = list.filter { x -> x > 0 }

์ž๋ฐ”์˜ stream์—์„œ ํ•„ํ„ฐ๋ง ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋žŒ๋‹ค์‹์„ ์ด์šฉํ•ด์„œ ๋ฆฌ์ŠคํŠธ์—์„œ ํŠน์ • ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ๋“ค๋งŒ ์„ ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ it ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

val positives = list.filter { it > 0 }

 

4. ์ปฌ๋ ‰์…˜์—์„œ ํŠน์ • ์š”์†Œ ์กด์žฌ์œ ๋ฌด ํ™•์ธํ•˜๊ธฐ

// ํŠน์ • ์ŠคํŠธ๋ง์ด ๋ฆฌ์ŠคํŠธ์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ
if ("john@example.com" in emailsList) { ... }

// ํŠน์ • ์ŠคํŠธ๋ง์ด ๋ฆฌ์ŠคํŠธ์— ์กด์žฌํ•˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธ
if ("jane@example.com" !in emailsList) { ... }

 

5. ์ŠคํŠธ๋ง ํฌ๋งคํŒ… (String Interpolation)

var name = "ํ™ฉ๋น„ํ™"
println("Name $name")

์ŠคํŠธ๋ง ๋‚ด์— ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์œผ๋กœ ์ž๋ฐ”์˜ ์ŠคํŠธ๋ง ํฌ๋งคํ„ฐ์™€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์ด๋‹ค.

 

6. ์ธ์Šคํ„ด์Šค ๊ฒ€์‚ฌ (Instance Check)

when (x) {
    is Foo -> ...
    is Bar -> ...
    else   -> ...
}

์ฝ”ํ‹€๋ฆฐ์—์„œ when ์€ ์ž๋ฐ”์˜ switch ๋ฌธ๊ณผ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์œผ๋กœ ์ข€ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ switch๋ฌธ์„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

 

7. Map ์ˆœํšŒํ•˜๊ธฐ (Traversing a map/list of pairs)

for ((k, v) in map) {
    println("$k -> $v")
}

์ž๋ฐ”์—์„œ๋Š” keySet์ด๋‚˜ values๋ฅผ ๊ฐ๊ฐ ๊ฐ€์ ธ์™€์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ–ˆ์ง€๋งŒ ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” key, value ๋ฅผ ๋™์‹œ์— ๊ฐ€์ ธ์™€์„œ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

8. ๋ฒ”์œ„ ์‚ฌ์šฉ๋ฒ•

loop๋ฅผ ์œ„ํ•ด์„œ๋Š” ํŠน์ • ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•ด์ค˜์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋‹ค์–‘ํ•œ ๋ฒ”์œ„์ง€์ •๋ฒ•์„ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ๋‹ค.

for (i in 1..100) { ... }  // closed range: 100 ํฌํ•จ
for (i in 1 until 100) { ... } // half-open range: 100 ๋ฏธํฌํ•จ
for (x in 2..10 step 2) { ... }	// 2๋ถ€ํ„ฐ 2์”ฉ ์ฆ๊ฐ€ํ•˜๋ฉด์„œ 10๊นŒ์ง€ ...
for (x in 10 downTo 1) { ... }	// 10๋ถ€ํ„ฐ 1์”ฉ ๊ฐ์†Œํ•˜๋ฉด์„œ 1๊นŒ์ง€ ...
if (x in 1..10) { ... }	// ๋งŒ์•ฝ x๊ฐ€ 1์ด์ƒ 10์ดํ•˜๋ฉด ...

 

9. Read-Only List/Map

val list = listOf("a", "b", "c")
val map = mapOf("a" to 1, "b" to 2, "c" to 3)

listOf, mapOf ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ๊ธฐ์ „์šฉ ๋ฆฌ์ŠคํŠธ๋‚˜ ๋งต์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

 

10. ํ‚ค๋ฅผ ์ด์šฉํ•œ ๋งต์˜ ๊ฐ’ ์ฝ์–ด์˜ค๊ธฐ

println(map["key"])
map["key"] = value

์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ๋งต์˜ ์š”์†Œ์— ์ ‘๊ทผํ•  ๋•Œ ๋ฐฐ์—ด์ฒ˜๋Ÿผ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

11. Lazy ์†์„ฑ

val p: String by lazy {
    // compute the string
}

 

12. ํ™•์žฅ ํ•จ์ˆ˜ (Extension Functions)

fun String.spaceToCamelCase() { ... }

"Convert this to camelcase".spaceToCamelCase()

String์˜ ํ™•์žฅํ•จ์ˆ˜๋ฅผ ์ž„์˜๋กœ ์ถ”๊ฐ€์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค

 

13. ์‹ฑ๊ธ€ํ„ด ๊ฐ์ฒด ์ƒ์„ฑํ•˜๊ธฐ

object Resource {
    val name = "Name"
}

 

14. if not null ์„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ

val files = File("Test").listFiles()

println(files?.size)

files์˜ size๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ nullable์„ ์˜๋ฏธํ•˜๋Š” ?๋ฅผ ๋ถ™์—ฌ์ฃผ๋ฉด not null์ผ ๊ฒฝ์šฐ์—๋งŒ ์‹คํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค. ๋งŒ์•ฝ files๊ฐ€ null์ด๋ผ๋ฉด null์ด ์ถœ๋ ฅ๋œ๋‹ค.

 

15. if not null and else

val files = File("Test").listFiles()

println(files?.size ?: "empty")

์ด๋ฒˆ์—๋Š” if not null ์— else ์กฐ๊ฑด์„ ๋ถ™์—ฌ null์ด๋ฉด "empty" ๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

 

16. null์ผ ๊ฒฝ์šฐ ๋ฌธ(statement) ์‹คํ–‰ํ•˜๊ธฐ

val values = ...
val email = values["email"] ?: throw IllegalStateException("Email is missing!")

 

17. possibly empty collection์—์„œ ์ฒซ๋ฒˆ์งธ ์š”์†Œ ๊ฐ€์ ธ์˜ค๊ธฐ

val emails = ... // might be empty
val mainEmail = emails.firstOrNull() ?: ""

 

18. null์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์‹คํ–‰ํ•˜๊ธฐ

val value = ...

value?.let {
    ... // ๋ธ”๋Ÿญ๋‚ด์˜ ๋ฌธ์žฅ์€ value๊ฐ€ not null์ผ ๊ฒฝ์šฐ์— ์‹คํ–‰ํ•œ๋‹ค
}

 

19. nullable Boolean

val b: Boolean? = ...
if (b == true) {
    ...
} else {
    // `b` is false or null
}

Booleanํƒ€์ž…์˜ ๋ณ€์ˆ˜๊ฐ€ null์ธ์ง€ ์•„๋‹Œ์ง€ ๋ณ„๋„๋กœ ๊ฒ€์‚ฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

20. ๋‘ ๋ณ€์ˆ˜์˜ ๊ฐ’ ์Šค์™‘ํ•˜๊ธฐ

var a = 1
var b = 2
a = b.also { b = a }

์ž๋ฐ”์—์„œ๋Š” ๋‘ ๋ณ€์ˆ˜์˜ ๊ฐ’์„ swapํ•  ๋•Œ ์ž„์‹œ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€๋กœ ๋งŒ๋“ค์–ด์„œ swapํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด์ง€๋งŒ ์ฝ”ํ‹€๋ฆฐ์—์„œ๋Š” ๊ทธ๋Ÿด ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

์ด์™ธ์—๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ž๋ฐ”๋ณด๋‹ค ๋” ์‰ฝ๊ณ  ๊ฐ„๊ฒฐํ•ด์ง„ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ๋ฒ•์ด ์žˆ์œผ๋‚˜ ์ด ์ •๋„๋งŒ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋จธ์ง€๋Š” ์•„๋ž˜ ์ถœ์ฒ˜์— ์–ธ๊ธ‰ํ•œ ์ฝ”ํ‹€๋ฆฐ ๊ณต์‹์‚ฌ์ดํŠธ์—์„œ ํ™•์ธํ•ด๋ณด์„ธ์š”.

 

์–ด๋Š ์ •๋„ ๊ธฐ๋ณธ์ ์ธ ๋ฌธ๋ฒ•์— ์ต์ˆ™ํ•ด์ง€๋ฉด ์‰ฌ์šด ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œํ’€์ด๋ฅผ ์ฝ”ํ‹€๋ฆฐ์œผ๋กœ ํ•˜๋ฉด์„œ ๋น ๋ฅด๊ฒŒ ์ตํ˜€๋ณผ ๊ณ„ํšŒ์ž…๋‹ˆ๋‹ค.

 

 

 

์ถœ์ฒ˜ : https://kotlinlang.org/docs/reference/idioms.html