안녕하세요!

FE 개발자 유진주입니다.

App/Android

[모바일소프트웨어] Kotlin 학습하기

ypearl 2023. 9. 19. 14:21

Kotlin 학습하기

참고 링크 : Hello world | Kotlin Documentation (kotlinlang.org)

fun main() {
    if (true){
        println("Hello!\\n")
    }
    println("Mobile Software")
    // Hello, world!
}

In Kotlin:

Variables

  • read-only variables with val : val은 값을 바꿀 수 없음
  • mutable variables with var

: val이든, var이든 초기값을 주지 않고 선언 불가.

(만약, 초기값을 배정하지 않을 경우는 타입을 명시해주어야 함)

var test: Int
val test2: String

test2 = "a" // O
test2 = "b" // X (Error)

To assign a value, use the assignment operator =.

String templates

  • 자바와 달리 “”안에 있더라도 $가 있다면, 변수로 볼 수 있다.
fun main() {
    val name = "Mary"
    val age = 20
    // Write your code here
    println("$name is $age years old")
}

In total, Kotlin has the following basic types:

Category Basic types

Integers Byte, Short, Int, Long
Unsigned integers UByte, UShort, UInt, ULong
Floating-point numbers Float, Double
Booleans Boolean
Characters Char
Strings String
fun main() {
    val a : Int = 1000
    val b : String = "log message"
    val c : Double = 3.14
    val d : Long = 100_000_000_000_000
    val e : Boolean = false
    val f : Char = '\\n'
}

Collections

Collection type Description

Lists Ordered collections of items 들어간 순서대로, 중복 허용
Sets Unique unordered collections of items 중복 허용하지 않음
Maps Sets of key-value pairs where keys are unique and map to only one value

[참고] 보통 read-only을 더 많이 쓴다.

- List

Lists store items in the order that they are added, and allow for duplicate items.

To create a read-only list ([List](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/>)), use the [listOf()](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/list-of.html>) function. (더 많이 씀)

To create a mutable list ([MutableList](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list.html>)), use the [mutableListOf()](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-list-of.html>) function.

// Read only list
val readOnlyShapes = listOf("triangle", "square", "circle")
println(readOnlyShapes)
// [triangle, square, circle]

// Mutable list with explicit type declaration
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
println(shapes)  // 명시적 선언은 <> 를 사용한다.
// [triangle, square, circle]

mutableList 가 List보다 하위타입. 따라서 mutableList를 List에 할당할 수 있다.

[ List(리스트)의 Method(메소드) ]

val readOnlyShapes = listOf("triangle", "square", "circle")
println("The first item in the list is: ${readOnlyShapes.first()}")
println("This list has ${readOnlyShapes.count()} items")
// This list has 3 items
println("circle" in readOnlyShapes)
// true

val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
// Add "pentagon" to the list
shapes.add("pentagon") 
println(shapes)  
// [triangle, square, circle, pentagon]

// Remove the first "pentagon" from the list
shapes.remove("pentagon") 
println(shapes)  
// [triangle, square, circle]

- Set

Whereas lists are ordered and allow duplicate items, sets are unordered and only store unique items.

To create a read-only set ([Set](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/>)), use the [setOf()](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/set-of.html>) function.

To create a mutable set ([MutableSet](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-set/>)), use the [mutableSetOf()](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-set-of.html>) function.

[ Set(집합)의 Method(메소드) ]

- Map

: 키 값 존재

To create a read-only map ([Map](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/>)), use the [mapOf()](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-of.html>) function.

To create a mutable map ([MutableMap](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-map/>)), use the [mutableMapOf()](<https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-map-of.html>) function.

  • key와 value의 값은 to를 사이에 두고 작성한다.
// Read-only map
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(readOnlyJuiceMenu)
// {apple=100, kiwi=190, orange=100}

// Mutable map with explicit type declaration
val juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(juiceMenu)
// {apple=100, kiwi=190, orange=100}
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println("orange" in readOnlyJuiceMenu.keys)
// true
println(200 in readOnlyJuiceMenu.values)
// false

Control flow

- Conditional expressions

Kotlin provides if and when for checking conditional expressions.

if보다는 when이 더 안전하다.

- If

To use if, add the conditional expression within parentheses () and the action to take if the result is true within curly braces {}:

val d: Int
val check = true

if (check) {
    d = 1  // 둘 중에 한 번만 초기화하는 거기에 가능
} else {
    d = 2  // 둘 중에 한 번만 초기화하는 거기에 가능
}

println(d)
// 1

- When

Use when when you have a conditional expression with multiple branches. when can be used either as a statement or as an expression.

다중 선택 허용 구성, switch와 달리 when은 범위 설정도 가능.

Here is an example of using when as a statement:

  • Place the conditional expression within parentheses () and the actions to take within curly braces {}.
  • Use > in each branch to separate each condition from each action.
val obj = "Hello"

when (obj) {
    // Checks whether obj equals to "1"
    "1" -> println("One")
    // Checks whether obj equals to "Hello"
    "Hello" -> println("Greeting")
    // Default statement
    else -> println("Unknown")     
}
// Greeting

Here is an example of using when as an expression. The when syntax is assigned immediately to a variable: 대입 연산의 우측에 수식과 같은 형식으로도 사용 가능!

**val** obj = **"Hello"**    

**val** result = **when** (obj) {
    // If obj equals "1", sets result to "one"
    **"1"** -> **"One"**
    // If obj equals "Hello", sets result to "Greeting"
    **"Hello"** -> **"Greeting"**
    // Sets result to "Unknown" if no previous condition is satisfied
    **else** -> **"Unknown"**
}
println(result)
// Greeting

- Ranges (..)

: ..은 올라가는 방향. 반대로 하고 싶으면, downTo 사용

- Loops

The two most common loop structures in programming are for and while. Use for to iterate over a range of values and perform an action. Use while to continue an action until a particular condition is satisfied.

For

Using your new knowledge of ranges, you can create a for loop that iterates over numbers 1 to 5 and prints the number each time.

While

: 그 안에는 변경될 수 있는 값이 들어가야 한다. (⇒ 무한반복 피하기)

아래 링크 확인하기 (셀프실습)

Conditions and loops.

Functions

fun hello() {
    return println("Hello, world!")
}

fun main() {
    hello()
    // Hello, world!
}
  • 명시적인 return 타입이 있어야 한다면, () : return 타입 형식으로!
fun sum(x: Int, y: Int): Int {
    return x + y
}

fun main() {
    println(sum(1, 2))
    // 3
}

Named arguments

순서를 정확하게 모를 때, 이름을 지목해서 값을 주는 방법

fun printMessageWithPrefix(message: String, prefix: String = "Info") {
    println("[$prefix] $message")
}

fun main() {
    // Uses named arguments with swapped parameter order
    printMessageWithPrefix(prefix = "Log", message = "Hello")
    // [Log] Hello
}

Default parameter values

Functions without return

아무것도 return하지 않음을 명시

fun printMessage(message: String) {
    println(message)
    // `return Unit` or `return` is optional
}

fun main() {
    printMessage("Hello")
    // Hello
}

Single-expression functions(★)

하나의 수식으로 관리되는 함수. 기존 함수를 보다 간단한 방식으로 표현 가능!

fun sum(x: Int, y: Int) = x + y

fun main() {
    println(sum(1, 2))
    // 3
}

Lambda expressions

Kotlin allows you to write even more concise code for functions by using lambda expressions.

For example, the following uppercaseString() function:

fun main() {
    println({ string: String -> string.uppercase() }("hello"))
    // HELLO
}

Lambda expressions can be used in a number of ways. You can: <Lambda 함수의 특징>

→ 값처럼 취급할 수 있다!

Assign to variable

Pass to another function

val numbers = listOf(1, -2, 3, -4, 5, -6)
val positives = numbers.filter { x -> x > 0 }
val negatives = numbers.filter { x -> x < 0 }
println(positives)
// [1, 3, 5]
println(negatives)
// [-2, -4, -6]
val numbers = listOf(1, -2, 3, -4, 5, -6)
val doubled = numbers.map { x -> x * 2 }
val tripled = numbers.map { x -> x * 3 }
println(doubled)
// [2, -4, 6, -8, 10, -12]
println(tripled)
// [3, -6, 9, -12, 15, -18]

Function types

<aside> 💡 fun test(): Int -> Double = ~

For example: (String) -> String or (Int, Int) -> Int.

</aside>

val upperCaseString: (String) -> String = { string -> string.uppercase() }

fun main() {
    println(upperCaseString("hello"))
    // HELLO
}

Return from a function

fun toSeconds(time: String): (Int) -> Int = when (time) { // return 타입이 람다식
    "hour" -> { value -> value * 60 * 60 }
    "minute" -> { value -> value * 60 }
    "second" -> { value -> value }
    else -> { value -> value }
}

fun main() {
    val timesInMinutes = listOf(2, 10, 15, 1)
    val min2sec = toSeconds("minute")
    val totalTimeInSeconds = timesInMinutes.map(min2sec).sum()
    println("Total time is $totalTimeInSeconds secs")
    // Total time is 1680 secs
}

Trailing lambda

: 함수의 형식 바깥에 쓸 수 있음. function의 마지막 파라미터일 떄 Trailing을 붙일 수 있다.

// The initial value is zero. 
// The operation sums the initial value with every item in the list cumulatively.
println(listOf(1, 2, 3).fold(0, { x, item -> x + item })) // 6

// Alternatively, in the form of a trailing lambda
println(listOf(1, 2, 3).fold(0) { x, item -> x + item })  // 6

Classes

Properties

Characteristics of a class's object can be declared in properties. You can declare properties for a class:

class Contact(val id: Int, var email: String)
//constructor 생략 가능 (그 안에 각각의 멤버 변수들 열거해서 작성 가능)

class Contact(val id: Int, var email: String) {
    val category: String = ""
}
//추가 프로퍼티는 중괄호 안에 작성 가능

Data classes

: 새롭게 등장한 개념

To declare a data class, use the keyword data:

data class User(val name: String, val id: Int)

The most useful predefined member functions of data classes are:

Function Description

.toString() Prints a readable string of the class instance and its properties.
.equals() or == Compares instances of a class.
.copy() Creates a class instance by copying another, potentially with some different properties.

Null safety

Nullable types

Kotlin supports nullable types which allows the possibility for the declared type to have null values. By default, a type is not allowed to accept null values. Nullable types are declared by explicitly adding ? after the type declaration.

: 타입의 선언부 끝에 물음표(?)를 붙이면 Null을 허용

 

Check for null values

fun lengthString(maybeString: String?): Int? = maybeString?.length
// 값이 있으면 .length 연산하고, 없으면(NULL) Null값 반환

fun main() { 
    var nullString: String? = null
    println(lengthString(nullString))
    // null
}
person.company?.address?.country
// 이렇게도 사용 가능함 (최종 country 값 반환)

'App > Android' 카테고리의 다른 글

[Android] API Key 생성 (Google Map)  (1) 2023.12.06