Kotlin

Kotlin 공부 - 함수, 람다, 고차 함수, infix 함수, scope함수

자다르 2022. 4. 13. 10:27

※ 이해와 학습을 위해 원본 코드의 추가/수정이 있을 수 있습니다.

※ 인프런 강의: 개복치개발자님의 [입문편] 안드로이드를 위한 코틀린(Kotlin) 문법의 학습 기반으로 작성했습니다.

※ InterviewBit Kotlin 설명을 참고합니다.

※ 정보의 공유 사회(https://ddolcat.tistory.com/) 설명 및 예제를 참고합니다.

※ Programize(http://learning.coreref.com/www.programiz.com/kotlin-programming) 설명 및 예제를 참고합니다.

※ Udemy The Complete Android 12 & Kotlin Development Masterclass 설명 및 예제를 참고합니다.


  • 함수-#1
// 함수
// 함수는 기능이다
fun main() {
   sum(10,20)
}

fun sum(a : Int, b : Int){
    println(a+b)
}

결과
===============
30
  • 함수-#2 - 결과값 반환하기
// 함수
// 결과값을 반환하기
fun main() {
   val sumValue = sum2(20,40)
   println(sumValue)
}

fun sum2(a : Int, b : Int) : Int {
    val result = a + b
    return result
}

결과
===================
60
  • (응용) 함수-#3 - 간단한 계산기 만들어보기-1 
// 함수
// 함수를 이용해 간단한 계산기 만들어보기

fun main (){
    println(sum(3,4))
    println(minus(3,4))
    println(multiply(3,4))
    println(divide(3,4))
    println(remainder(3,4))
}

// 더하기
fun sum(num1: Int, num2: Int): Int {
    return num1 + num2
}

// 빼기
fun minus(num1: Int, num2: Int): Int {
    return num1 - num2
}

// 곱하기
fun multiply(num1: Int, num2: Int): Int {
    return num1 * num2
}

// 나누기
fun divide(num1: Int, num2: Int): Int {
    return num1 / num2
}

// 나머지
fun remainder(num1 : Int, num2: Int) : Int {
    return num1 % num2
}

결과
==========================
7
-1
12
0
3
  • (응용) 함수 - 간단한 계산기-#2
// 함수
// 함수를 이용해 간단한 계산기 만들어보기 - 응용

fun main (){
    println(calculator(3, 4, "s"))
    println(calculator(3, 4, "m"))
    println(calculator(3, 4, "p"))
    println(calculator(3, 4, "d"))
    println(calculator(3, 4, "r"))
}

fun calculator(num1 : Int, num2: Int, mode : String) : Int {
    var result = 0
    when(mode) { // when(mode):s
        "s" -> { // sum
            result = num1 + num2
        }
        "m" -> { // minus
            result = num1 - num2
        }
        "p" -> { // multiply
            result = num1 * num2
        }
        "d" -> { // divide
            result = num1 / num2
        }
        "r" -> { // remainder
            result = num1 % num2
        }
    } // when(mode):e
    return result
} // fun calculator():e

결과
==================
7
-1
12
0
3
  • 람다(Lambda)란

// 람다

fun main() {
   println(a())
   println(b())
   println(sum(1,2))
   println(sum2(1,2))
   println(sum3(1,2))
   println(sum4(1,2))
   
   println(sumString("1","2"))
   println(sumString2("1","2"))
   println(sumString("1","2"))
   //println(sumString(1,2))
}

fun a(): String {
    return "text"
}

fun b() = "text"

fun sum(a : Int, b : Int) : Int {
    return a+b
}

val sum2 = {a : Int, b : Int -> a+b }
val sum3 : (Int, Int) -> Int = { a,b -> a+b }
val sum4 : (Int, Int) -> Int? = { a,b -> null }

fun sumString(a: String, b: String) : String {
    return "String1 : $a, String2 : $b"
}

val sumString2 = {a : String, b : String -> "String1 : $a, String2 : $b" }
val sumString3 : (String, String) -> String = { a,b -> "String1 : $a, String2 : $b" }

결과
==============================
text
text
3
3
3
null
String1 : 1, String2 : 2
String1 : 1, String2 : 2
String1 : 1, String2 : 2
  • 고차 함수(High order function)란 & Unit의 사용
// 고차함수(High order function)
// 다른 함수를 인자로 받거나 함수를 반환하는 함수
// f(x) = x -> f(f(x)) = x

fun main() {
   println(testSum(1,2))
   println(testLambdaSum(1,2))
   sum(1,2, { a : Int, b : Int -> a + b })
   sum(1,2) { a : Int, b : Int -> a + b }
   sum(1,2, ::testSum)
   
   printTest("abc")
   highPrintTest(::printTest)
   test1()
}

fun testSum(a: Int, b: Int) : Int {
    return a+b
}

val testLambdaSum : (Int, Int) -> Int = { a, b -> a+b }

fun sum(a : Int, b : Int, operation : (Int, Int) -> Int) {
    println("$a $b")
    println(operation(a,b))
}

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

// Unit: 아무것도 return하지 않는다
fun highPrintTest(operation : (String) -> Unit){
    operation("bbb")
}

fun test1() : Unit {
    println("abc")
}

fun test2() : Unit {
    println("abc2")
    return
}

fun test3() : Unit {
    println("abc3")
    return Unit
}


결과
=============================
3
3
1 2
3
1 2
3
1 2
3
abc
bbb
abc
  • infix 함수
// infix 함수 - 중간에 끼워 넣기

fun main() {
   println(10 sum1 20)
   println(3 multiply1 5)
   println(10 sum2 20)
   println("Apple" sum3 " Pie")
   println(10 showList 20)
}

infix fun Int.sum1( num : Int ) : Int = this + num
infix fun Int.multiply1( 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 Int.showList( num : Int ) : List<Int> {
    val list = mutableListOf<Int>()
    for( i in this..num ) {
        list.add(i)
    }
    return list
}

결과
============================
30
15
30
Apple Pie
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
  • let
// let : non null일 때 사용, non null일 때 동작하고, null일 때 동작하지 않음

fun main() {
   var str : String? = "hi"
   println(str?.length)
   
   val length1 = str?.let {
       println("As of not null, print string:"+it)
       it.length
   }
   
   println("As of not null, print length:"+length1)
   
   val str2 : String? = null
   val length2 = str2?.let {
       println(it)
       it.length
   }
   println(length2)
}

출력
================
2
As of not null, print string:hi
As of not null, print length:2
null
  • with
// with: 컨텍스트 내부에서 함수를 호출

fun main(){
    val numbers = mutableListOf("a","b","c","d")
    println(numbers.first())
    println(numbers.last())

	val firstAndLast = with(numbers){
    	"First is: ${ first() }, and last is ${ last() }"
	}

	println(firstAndLast)

}

결과
=====================
a
d
First is: a, and last is d
  • run
// run: 객체 초기화와 return값 계산이 필요할 때 사용

fun main(){
    
    val service = multiPortService("www.naver.com", 80)
    println(service.prepareRequest())
    
    val result1 = service.query(service.prepareRequest() + " to port ${service.port}")
    println(result1)
    
    val result2 = service.run {
        port = 8080
        query( prepareRequest() + " to port ${port}")
    }
    println(result2)
}

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

결과
=============================
기본 요청 url: www.naver.com
결과 query 기본 요청 url: www.naver.com to port 80
결과 query 기본 요청 url: www.naver.com to port 8080
  • apply
// apply: 값을 반환하지 않고 객체 구성에대해 주로 사용

fun main(){
    
    val tester1 = Person("Tester1")
    println(tester1)
    
    tester1.age = 20
    tester1.city = "Seoul"
    
    println(tester1)
    
    val tester2 = Person("Tester2").apply {
        age = 21
        city = "Busan"
    }
    
    println(tester2)
    
}

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

결과
================
Person(name=Tester1, age=0, city=)
Person(name=Tester1, age=20, city=Seoul)
Person(name=Tester2, age=21, city=Busan)
  • also
// also: 객체에대한 추가적인 작업


fun main(){
    val numbers = mutableListOf(1,2,3,4)
    println("$numbers 여기에 5를 추가합니다.")
    numbers.add(5)
    println(numbers)
    
    val numbers2 = mutableListOf(1,2,3,4)
    numbers2.also {
        println("$numbers2 여기에 5를 추가합니다.")
    }.add(5)
    println(numbers2)
}

결과
====================
[1, 2, 3, 4] 여기에 5를 추가합니다.
[1, 2, 3, 4, 5]
[1, 2, 3, 4] 여기에 5를 추가합니다.
[1, 2, 3, 4, 5]