# 1. Language/🔰 Kotlin

Kotlin # 함수/람다식/흐름제어/반복문

둥굴둥굴둥굴레차 2022. 6. 29. 16:40

🎈 함수

 

기본구성

 

예)

// 기본적인 함수 선언법
fun plusNumbers(firstNum: Int, secondNum: Int): Int {
    val result: Int = firstNum + secondNum

    return result
}

// plusNumbers 호출 방법 1
println(plusNumbers(10, 20))

// plusNumbers 호출 방법 2
val result: Int = plusNumbers(10, 20)
println(result)

////////////////////////////////////////////////////////

// 기본값이 있는 함수 선언법
fun plusNumbersWithDefault(firstNum: Int, secondNum: Int = 10): Int {
    return firstNum + secondNum

}

val result2: Int = plusNumbersWithDefault(10)
println(result2)

val result3: Int = plusNumbersWithDefault(10, 20)
println(result3)

////////////////////////////////////////////////////////

// 반환값이 없는 함수 선언법
// 1. Unit 기입 -> 추천
fun plusNumberWithNoReturn(firstNum: Int, secondNum: Int): Unit {
    val result4: Int = firstNum + secondNum
    println(result4)
}

plusNumberWithNoReturn(100, 200)

// 2. Unit 삭제 -> 추천
fun plusNumberWithNoReturn2(firstNum: Int, secondNum: Int) {
    val result4: Int = firstNum + secondNum
    println(result4)
}

plusNumberWithNoReturn(100, 200)

// 3. 반환하는 값이 없는 상태에서 return만 기입 -> 비추천
fun plusNumberWithNoReturn3(firstNum: Int, secondNum: Int) {
    val result4: Int = firstNum + secondNum
    println(result4)
    return
}

plusNumberWithNoReturn(100, 200)

////////////////////////////////////////////////////////

// 함수 선언을 간단하게 하는 방법
fun shortNumbers(firstNum: Int, secondNum: Int) = firstNum + secondNum
val result4: Int = shortNumbers(10, 100)
println(result4)

// 가변인자를 갖는 함수
fun plusMultipleNums(vararg  numbers: Int): Unit { // `반환값이 없고` 오로지 `출력`만 하는 함수이기 때문에  Unit을 적어줘야 한다!!
//    println(numbers) -> 이렇게 numbers를 출력해보려하면 [I@45fdd38d와 같은 값이 나온다.
    for(number in numbers){
        println(number)
    }
}
plusMultipleNums(1, 2, 3, 4, 5)

// 참고!!
// 함수에 return값이 있을 경우 -> 함수 사용 시 반드시 println해줘야 하며,
// 만약 return값이 없는 Unit일 때엔 -> 함수 선언 후 println안해줘도 된다.
//
// 함수 내부에서 부터 println해주고 있기 때문!
// 오히려 println해주게되면 kotlin.unit이 결과값과 함께 반환된다.

 


🎈 가변 파라미터

파라미터의 개수를 미리 정하지 않는 파라미터
(vararg <파라미터 이름>:<자료형>)

 

예)

(varrag inputs:Int)
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {

    중략...

    button.setOnClickListener {
    val result = add(10, 20, 30, 40, 50)
    showToast("결과 : ${result}")
    }
  }

    중략...

    fun add(vararg inputs:Int):Int {
        var output = 0

        for (num in inputs) {
        output += num
        }
        return output
      }

      fun showToast(message:String) {
      Toast.makeText(applicationContext, message, Toast.LENGTH_LONG).show()
      }
    }

 


🎈 람다식

Kotlin은 일급객체

  • 일급객체의 특징
    • 변수 할당 : 함수를 변수에 할당할 수 있다.
      • 함수에 파라미터로 전달 : 함수를 호출할 때 파라미터로 전달할 수 있다.
      • 함수에서 반환 : 함수에서 반환될 수 있다.

 

함수를 변수에 할당할 때 익명함수람다식의 형태를 사용해야 한다.

 

익명함수

이름이 없는 함수. 함수를 정의하면서 즉시 할당하면 변수 이름만 있어도 되기 때문.

 

람다식

함수의 축약형태. 중괄호 안에 실행코드가 들어간 익명함수.

{ <실행될 문장>}

 

예) { x, y -> x + y }

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 변수에 함수 할당 (람다식 함수만 할당 가능)
        button.setOnClickListener {
            val addFunc = {a:Int, b:Int -> a + b}
            val result = addFunc(10, 70)
            textView.setText("더하기 결과 : ${result}")
        }

 

fun addTwoNumbers(number1: Int, number2: Int): Int {
    return number1 + number2
}

//고차함수
fun addTenNine(function: (Int, Int) -> Int) {
    val result: Int = function(10, 9)
    println("결과는 $result 입니다")
}

addTenNine(::addTwoNumbers)

// 람다
// 풀버전
val addTenNine2: (Int, Int) -> Int = {number1: Int, number2: Int ->
    val result = number1 + number2
    result
}


// 람다
// 풀버전2 - 람다함수 자체로 고차함수기 때문에 별도의 연산자 없이 변수에 담을 수 있다.
val addTenNine3: (Int, Int) -> Int = {number1: Int, number2: Int ->

    number1 + number2
}
addTenNine(addTenNine3) // 람다함수를 인자로 사용하는 경우에는 ::을 사용할 필요 없음.

// 생략버전 1
val addTenNine4: (Int, Int) -> Int = {number1, number2 ->

    number1 + number2
}
addTenNine(addTenNine4)

// 생략버전 2
val addTenNine5 = {number1: Int, number2: Int ->

    number1 + number2
}
addTenNine(addTenNine5)

// 완전 간단한 버전
addTenNine {number1, number2 ->  number1 + number2}

// 파라미터가 없는 람다 함수
val addTenNine6: () -> Int = {
    10 + 9
}

val addTenNine7: (Int) -> Int = {
    10 + 9
}

🎈 if 구문 & When 구문

 

 

//if
val number1: Int = 10

if (number1 == 10) {
    println("number1은 10이다.")
} else if (number1 == 20) {
    println("number1은 20이다.")
} else {
    println("number1은 10도 20도 아니다")
}

// 조건이 아주 간단한 경우1
if (number1 == 10) println("number1은 10이다.")
else if (number1 == 20) println("number1은 20이다.")
else println("number1은 10도 20도 아니다")

// 조건이 아주 간단한 경우2
val number2: Int = 10 + 20
val number3: Int = if (number2 > 30) 40 else 50
println(number3)


//when
val number4: Int = 5
when (number4) {
    5 -> {
        println("5 입니다")
    }
    6 -> {
        println("6 입니다")
    }
    else -> {
        println("모르겠습니다")
    }
}

// 간단히 만들면 아래와 같다.
when (number4) {
    5 -> println("5 입니다")
    6 -> println("6 입니다")
    else -> println("모르겠습니다")
}

// 에러
//when (number4) {
//    5 -> println("5 입니다")
//    6 -> println("6 입니다")
//    "나는 글자" -> println("글자 입니다.")
//    is Boolean -> println("boolean")
//    in 1..10 -> println("숫자는 1과 10 사이에 들어있습니다.")
//    else ->
//        println("모르겠습니다")
//}

 


🎈 for구문

 

 

//for 반복문

for (value in 1..10) {
    println("반복")
}
println("//////////////////")

for (value in 0..5 step 2) {
    println("반복2")
}
println("//////////////////")

for (value in 5 downTo 0) {
    println("반복3")
}
println("//////////////////")

val numbers = listOf<Int>(0, 1, 2, 3)

for (number in numbers) {
    println(number)
}
println("//////////////////")

for (i in 1..numbers.size) {
    println("반복4")
}
println("//////////////////")

for (i in 0 until numbers.size) {
    println("반복5")
}
println("//////////////////")

for ((index, number) in numbers.withIndex()) {
    println("" + index + "|" + number)
}
println("//////////////////")

//////////////////////////////////////////////////////////
//forEach
numbers.forEach {
    println(it)
}
println("//////////////////")

numbers.forEach { number ->
    println(number)
}

 

🎈 while구문

//While

var i = 0
while(i<5){
    if(i%2 == 0)
        println("짝")
    else
        println("홀")
    i++ // 이 부분이 없으면 무한루프에 빠진다.
}
println("//////////////////")

//////////////////////////////////////////////////////////
//do-While

var j = 0
do {
    println("시작")
    j++
}while(j<5)

🎈 흐름제어에 필요한 키워드

 

 

//break

for(i in 1..3){
    for(j in 1..3){
        if(j == 2) break
        else println("j")
    }
}
println("/////////////////")

for(i in 1..3){
    println("i : " + i)
    for(j in 1..3){
        if (j == 2) break
        else println("j : " + j)
    }
}
println("/////////////////")

//continue

for(i in 1..3){
    println("i : " + i)
    for(j in 1..3){
        if (j == 2) continue
        else println("j : " + j)
    }
}
println("/////////////////")

//return
fun returnFun(): Unit {
    for (i in 1..3) {
        println("i : " + i)
        for (j in 1..3) {
            if (j == 2) return
            else println("j : " + j)
        }
    }
}

returnFun()
println("/////////////////")

// label
// (1) break에 라벨
loop@for(i in 1..3){
    println("i : " + i)
    for(j in 1..3){
        if (j == 2) break@loop
        else println("j : " + j)
    }
}
println("/////////////////")

// (2) continue에 라벨
loop@for(i in 1..3){
    println("i : " + i)
    for(j in 1..3){
        if (j == 2) continue@loop
        else println("j : " + j)
    }
}
println("/////////////////")

// (3) forEach에 라벨
// -> forEach에는 break와 continue 사용불가. return만 됨.
// 아래처럼 잘 사용하진X

listOf<Int>(1, 2, 3).forEach loop@{
    if(it == 2) return@loop
    else println(it)
}
 val numbers = intArrayOf(5, 10, 15)

 for (number in numbers){ // forEach와 동일
     println(number)
 }

 println("///////////////////")

 // 값과 인덱스 모두 필요할 때
 for ((i, v) in numbers.withIndex()){ // forEachIndexed와 동일
     println(""+i+"|"+v)

 }

 println("///////////////////")

 // 인덱스만 필요할 때
 for ( index in numbers.indices) {
     println(index)
 }

 println("///////////////////")
 
//numbers.forEachIndexed { index, i ->
//    // 본문에서 사용될 변수 이름을 기본 제공으로 사용
//}
//
// numbers.forEachIndexed { index, value ->
//     // 본문에서 사용될 변수 이름을 임의로 변경해서 사용
// }