본문 바로가기
혼공노트

코틀린에 대한 작은 정리 (2)

by 김비거 2024. 4. 6.

 

 

* 이 글은 인프런 강의 <[입문편] 안드로이드를 위한 코틀린(Kotlin) 문법>을 보고 정리한 글입니다.

 


람다 (Lambda)

 

fun main() {
    println(sumString("1", "2"))
    println(sumStringTwo("1", "2"))
    println(sumStringTypeTwo("1", "2"))
}

fun sumString(a : String, b : String) : String {
    return "string1 : $a string2 : $b"
}
val sumStringTwo = {a : String, b : String -> "string1 : $a string2 : $b"}
val sumStringTypeTwo : (String, String) -> String  = {a, b -> "string1 : $a string2 : $b"}

 

람다 = 즉시 표현식

{ } = 실행내용

-> = 그래서, 출력값은

{ } 안에 자료형을 선언하거나

자료형을 먼저 선언하고 { } 실행내용 씀

 

 

고차함수 (High-Order Function)

 

fun main() {  
    printTest("abc")
    highPrintTest(::printTest) // 고차함수 '::'
}

fun printTest(str : String) {
    println(str)
}

fun highPrintTest(operation : (String) -> Unit) {
    operation("bbb")	// printTest("bbb")
}

 

함수가 f(x)라면

고차함수 = f(f(x))

operation = 함수 안에 넣을 함수

:: = 함수 선언시 안에 넣을 함수 앞에 씀

 

 

제네릭 (generic)

 

fun main() {
    val box1 = Box(10)	// Int 타입
    println(box1.value)
    
    val box2 = Box("10") // String 타입
    println(box2.value)
    
    testFun("a") // Int 타입
    testFun(123) // String 타입

}

class Box<T>(test : T) { // 타입캐스팅 ㄴㄴ
    var value = test
}

fun <T> testFun(a : T) { // 타입캐스팅 ㄴㄴ
    println(a)
}

 

제네릭 = 타입캐스팅 ㄴㄴ (타입이 무엇인지 상관 안함)

class 이름 다음에 <T> 씀. 자료형은 T

fun 이름 전에 <T> 씀. 자료형은 T 

 

 

Object

 

fun main() {
    val test1 = TestClass()
    val test2 = TestClass()
    
    test1.count = 10
    
    println(test1.count) // 10
    println(test2.count) // 0
    
    val test3 = testObject
    val test4 = testObject
    
    test3.count = 10
    println(test3.count) // 10
    println(test4.count) // 10 (전역)
    
    
    val test5 = TestObjectClass()
    val test6 = TestObjectClass()
    
    test5.plusBtn()
    println(TestObjectClass.number) // 1
    test5.plusBtn()
    println(TestObjectClass.number) // 2
    test6.minusBtn()
    println(TestObjectClass.number) // 1 (전역)
    
}

class TestClass { // 그냥 클래스
    var count = 0
}

object testObject{ // object
    var count = 0
}

class TestObjectClass {
    companion object { // 클래스 안의 object
        var number = 0
    }
    
    fun plusBtn() {
        number++
    }
    
    fun minusBtn() {
        number--
    }
}

 

object = 객체 한 개만. 전역으로 사용.

companion = class 안에 object를 쓰기 위해 앞에 붙임.

 

 

지연 초기화(lateinit / lazy)

 

fun main() {
    
    lateinit var lateString : String // 미리 변수를 선언하고 나중에 값을 넣을 때 사용
    
    lateString = "a"
    lateString = "b" // 변경가능
    println(lateString) // b
    
    val lazyStirng : String by lazy { // 나중에 이 값들을 사용
        println("프린트")
        "lazyTestString"
    } // 변경불가
    println(lazyStirng) // "프린트" "lazyTestString"
}

 

lateinit = 미리 변수 선언 후 나중에 값을 넣겠음.

var 이전에 씀. 변경 가능.

by lazy = 나중에 값을 사용하겠음.

자료형 후에 씀. 변경 불가.

 

 

infix function

 

fun main() {
    println(10 sum1 20) // 30
    println(10 sum2 20) // 30
    
    println("apple" sum3 "grape") // applegrape
    println("사과" sum4 "포도") // 사과포도
    
    println(10 showList 15) // [10, 11, 12, 13, 14, 15]
}

infix fun Int.sum1(num : Int) : Int = this + num
infix fun Int.sum2(num : Int) : Int {
    return this + num
}

infix fun String.sum3(abc : String) : String = this + abc
infix fun String.sum4(abc : String) : String {
    return this + abc
}

infix fun Int.showList(num : Int) : List<Int> {
    val list  = mutableListOf<Int>()
    for (i in this..num) {
        list.add(i)
    }
    return list
}

 

infix = 중간에서 역할

this = infix 함수 사용시 앞단

인수는 infix 함수 사용시 뒷단

 

 

scope function

 

fun main() {
    //let : null이 아닐 때 동작, null일 때 동작 X
    val str : String? = "hi"
    val length = str?.let {
        println(it) // "hi"
        it.length
    }
    println(length) // 2
    
    val str2 : String? = null
    val length2 = str2?.let {
        println(it)
        println("실행") // 실행되지 않음
        it.length 
    } 
    println(length2) // null
    
    
    // with : 내부에서 함수 호출시
    val numbers = mutableListOf("a", "b", "c", "d")
    println(numbers.first()) // "a"
    println(numbers.last()) // "d"
    
    val firstAndLast = with(numbers) {
        "${first()} ${last()}"
    }
    println(firstAndLast) // "a d" 
}

 

let = null일 때 동작 안함.

with = 컨텍스트 내부에서 함수호출.

 

fun main() {
    // run : 객체 초기화, 반환값 계산
    val service = multiPortService("www.naver.com", 80)
    val result = service.run {
        query(prepareRequest() + " to port $port")
    }
    println(result) // 결과 query 기본 요청 url www.naver.com to port 80
    
    //apply : 값은 반환 X, 객체 구성에 대해 사용
    val tester = Person("Tester").apply{
        age = 21
        city = "Busan"
    }
    println(tester) // Person(name=Tester, age=21, city=Busan)
    
    // also : 객체 추가작업
    val numbers = mutableListOf(1, 2, 3, 4)
    numbers.also {
        println("$numbers 여기에서 5를 추가합니다.")
    }.add(5)
    println(numbers) // [1, 2, 3, 4, 5]
    
}

class multiPortService(var url : String, var port : Int) {
    fun prepareRequest() : String = "기본 요청 url $url"
    fun query(request : String) = "결과 query $request"
}

data class Person(
    var name : String,
    var age : Int = 0,
    var city : String = ""
)

 

run  = 객체 반환값 계산

apply = 객체 구성

also = 객체 추가작업

 

 

enum class

 

fun main() {
   
    println(Direction.NORTH) // NORTH
    
    Direction.values().forEach {
        println(it) // NORTH SOUTH WEST EAST
    }
        
    val direction = Direction.EAST
    when(direction) {
        Direction.NORTH -> {
            println("N")
        }
        Direction.SOUTH -> {
            println("S")
        }
        Direction.WEST -> {
            println("W")
        }
        Direction.EAST -> {
            println("E")
        }
    } // E
    
    
    val color = Color.RED
    when(color) {
        Color.RED -> {
            println(Color.RED.colorName)
        }
        Color.GREEN -> {
            println(Color.GREEN.colorName)
        }
        Color.BLUE -> {
            println(Color.BLUE.colorName)
        }
    } // "빨강"
   
    println(Device.DEVICEON.status) // ON
    Device.DEVICEON.status = "OFF" // 값 변경
    println(Device.DEVICEON.status) // OFF
}

enum class Direction {
    NORTH, SOUTH, WEST, EAST
}

enum class Color(val colorName : String) {
    RED("빨강"),
    GREEN("초록"),
    BLUE("파랑")
}

enum class Device(var status : String) {
    DEVICEON("ON"),
    NETWORK("OFF"),
    LOCATION("SEOUL")
}

 

enum class = 나열

 

 

 

댓글