References: Do it! 코틀린 프로그래밍

코틀린에서의 생성자에 대해 알아봅니다.

 

 

1. 생성자

 

생성자란 클래스를 통해 객체가 만들어 질 떄 기본적으로 호출되는 함수를 말합니다.

생성자를 선언하는 위치는 다음과 같습니다.

 

class 클래스이름 constructor(매개변수){ //주 생성자
    ...
    constructor(매개변수){ ... } //부 생성자
    [constructor(매개변수){ ... }] //추가 부 생성자
    ... 
}

 

코틀린에서는 위의 예시와 같이 여러 생성자를 선언할 수 있습니다.

이에 대해 좀 더 자세히 알아봅시다.

 

 

2. 부 생성자

 

부 생성자는 클래스 본문에 함수처럼 선언하는 생성자를 말합니다.

Bird 클래스를 예시로 부 생성자에 대해 알아보겠습니다.

 

class Bird{
    var name: String
    var wing: Int
    var beak: String
    var color: String
    constructor(name: String, wing: Int, beak: String, color: String){
        this.name = name
        this.wing = wing
        this.beak = beak
        this.color = color
    }
    fun fly() = println("Fly wing: $wing")
    fun sing(vol: Int) = println("Sing vol: $vol")
}
fun main() {
    val coco = Bird("myBird", 2, "short", "blue")
    coco.color = "yellow"
    println("coco.color: ${coco.color}")
    coco.fly()
    coco.sing(3)
}

 

Bird 클래스를 선언하고 내부에 부 생성자를 통해 프로퍼티를 초기화 해주었습니다.

fly와 sing는 메서드입니다.

 

위의 예시를 실행하면 결과는 다음과 같습니다.

입력 인자값을 달리한 채 부 생성자를 여러개 추가할 수 있습니다.

다음 예시를 통해 여러 부 생성자를 선언한 코드를 확인할 수 있습니다.

 

class Bird{
    var name: String
    var wing: Int
    var beak: String
    var color: String
    constructor(name: String, wing: Int, beak: String, color: String){
        this.name = name
        this.wing = wing
        this.beak = beak
        this.color = color
    }
    constructor(name: String, color: String){
        this.name = name
        this.wing = 2
        this.beak = "short"
        this.color = color

    }
    fun fly() = println("Fly wing: $wing")
    fun sing(vol: Int) = println("Sing vol: $vol")
}

 

주의할 점은 선언한 프로퍼티를 모두를 초기화 시켜줘야 한다는 것 입니다.

 

 

 

3. 주 생성자.

 

주 생성자는 클래스 이름과 함께 생성자 정의를 사용하는 방법입니다.

주 생성자는 클래스 이름과 본문 블록 사이에 선언합니다. 다음 예시를 통해 알아보도록 합시다.

 

class Bird constructor(_name: String, _wing:Int, _beak: String, _color: String){
    var name: String = _name
    var wing: Int = _wing
    var beak: String = _beak
    var color: String = _color
    fun fly() = println("Fly wing: $wing")
    fun sing(vol: Int) = println("Sing vol: $vol")
}

 

위와 같이 주 생성자를 정의할 수 있습니다. 이 경우 constructor 키워드는 생략할 수 도 있습니다.

** 단 가시성 지시자 혹은 어노테이션이 있다면 constructor 키워드를 생략할 수 없습니다.

 

 

내부의 프로퍼티를 주 생성자에서 선언 및 초기화를 실행하면 클래스 내부의 내용을 좀 더 간단하게 만들 수 있습니다.

다음 예시를 통해 프로퍼티 선언을 주 생성자 내부에서 진행하도록 하겠습니다.

 

class Bird(var name: String, var wing: Int, var beak: String, var color: String){
    fun fly() = println("Fly wing: $wing")
    fun sing(vol: Int) = println("Sing vol: $vol")
}

 

클래스 본문 내에 메서드만 존재해 더 간략한 클래스를 선언할 수 있습니다.

 

클래스를 생성할 때 필요한 초기화 작업을 클래스 내에 정의해 사용할 수도 있습니다.

다음 예시코드를 통해 클래스가 생성되며 수행되는 초기화 작업에 대해 알아봅시다.

 

class Bird(var name: String, var wing: Int, var beak: String, var color: String){
    init{
        println("###Start init block.###")
        println("Name: $name, Beak: $beak")
        this.sing(3)
        println("###End init block.###")
    }
    fun fly() = println("Fly wing: $wing")
    fun sing(vol: Int) = println("Sing vol: $vol")
}

fun main() {
    val coco = Bird("myBird", 2, "short", "blue")
}

 

클래스 내의 init을 통해 초기화 블럭을 선언할 수 있습니다.

실행 결과는 다음과 같습니다.

객채를 생성하면 초기화 블록 내의 코드가 자동으로 실행되는 것을 확인할 수 있습니다.

 

 

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 23. 다형성(Polymorphism)  (0) 2019.08.24
[Kotlin] 22. 상속(Inheritance)  (0) 2019.08.24
[Kotlin] 20. 예외 처리  (0) 2019.08.24
[Kotlin] 19. 라벨  (0) 2019.08.23
[Kotlin] 18. 반복문  (0) 2019.08.23

References: Do it! 코틀린 프로그래밍

코틀린에서의 예외처리 방법에 대해 알아봅니다.

 

 

1. 예외처리.

 

코틀린에서의 예외처리는 try ... catch(e: Exception) ... 으로 처리합니다.

DividedByZero예시를 통해 확인해 보겠습니다.

 

fun main() {
    val a = 1
    val b = 0
    val c: Int
    try{ c = a/b }
    catch(e: Exception){ println("Divided by 0 exception.") }
    finallyprintln("Finally block. ") }
}

 

위의 코드를 실행하면 다음과 같은 결과를 확인할 수 있습니다.

오류가 발생했다는 것을 확인할 수 있습니다.

 

지금은 코드가 짧으니 발생한 위치를 바로 찾을 수 있지만 대규포 프로그램에선 위치를 찾기가 힘들 수 도 있습니다.

이럴떄 스택 추적 기능을 이용하면 예외가 발생한 위치를 찾을 수 있습니다.

코드를 다음과 같이 수정해 봅시다.

 

fun main() {
    val a = 1
    val b = 0
    val c: Int
    try{ c = a/b }
    catch(e: Exception){
        println("Divided by 0 exception.")
        e.printStackTrace()
    }
    finally{ println("Finally block. ") }
}

 

예외 인자에 printStackTrace()를 실행하면 어디서 예외가 발생했는지 추적을 할 수 있습니다.

실행 결과는 다음과 같습니다.

 

 

2. 사용자 예외 클래스

 

코틀린은 여러 예외 클래스를 미리 지정해 둡니다. 미리 지정된 예외 클래스에 유저가 필요한게 없으면 어떻게 할까요?

유저가 원하는 예외클래스를 직접 정의하는 기능을 코틀린은 제공합니다.

 

다음과 같은 예시를 통해 확인해 보겠습니다

 

class InvalidNameException(message: String): Exception(message)
fun validateName(name: String){
    if(name.matches(Regex(".*\\d+.*"))) { throw InvalidNameException("Your name: $name : contains numerals.") }
}
fun main() {
    var name = "smoh92"
    try{ validateName(name) }
    catch(e: InvalidNameException){ println(e.message) }
    catch(e: Exception){ println(e.message) }
}

 

우선 InvalidNameException클래스를 정의합니다.

이후 위에서 정의한 예외 클래스를 사용하는 함수를 정의합니다. 이 함수는 이름에 숫자가 포함되면 InvalidNameException예외를 발생시킵니다.

 

실행 결과는 다음과 같습니다.

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 22. 상속(Inheritance)  (0) 2019.08.24
[Kotlin] 21. 생성자  (0) 2019.08.24
[Kotlin] 19. 라벨  (0) 2019.08.23
[Kotlin] 18. 반복문  (0) 2019.08.23
[Kotlin] 17. 조건문  (0) 2019.08.23

References: Do it! 코틀린 프로그래밍

코틀린에서의 라벨에 대해 알아봅니다.

 

 

1. 라벨

 

라벨이란 코드에서 특정 위치를 임의로 표기한것을 말합니다. @를 통해 사용할 수 있습니다.

@position

 

 

2. 람다식에서 라벨의 사용.

 

람다식을 포함한 함수에서 람다식에서의 리턴은 비지역 반환을 초래한다고 지난 글에서 다뤘습니다.

라벨을 이용하면 람다함수의 비지역 반환을 방지할 수 있습니다.

 

다음 예시코드는 라벨을 사용하여 람다함수의 비지역 반환을 방지하는 코드입니다.

 

fun lambdaFun(a: Int, b: Int, out: (Int, Int)->Unit) = out(a, b)
fun returnFun() {
    println("Start of returnFun")
    lambdaFun(10, 20)/** Start of lbl label. */lbl@{ a, b ->
        var result = a+b
        if(result >10) { return@lbl }
        println("result: $result")
    } /** End of lbl label. */
}
fun main() {
    returnFun()
}

 

lbl@ 를 통해 라벨을 지정하였습니다. 라벨이 유효한 범위는 람다식 한 블럭입니다.

실행결과는 다음과 같습니다.

 

 

3. 암묵적 라벨

 

람다 함수에는 위 처럼 명시적으로 라벨을 지정해 줄 수도 있지만 기본적으로 암묵적 라벨이라는것이 존재합니다.

암묵적라벨은 람다함수의 이름으로 자동 설정됩니다.

 

예를 들어 위의 코드를 암묵적 라벨을 사용하는 코드로 바꾸면 다음과 같습니다.

 

fun lambdaFun(a: Int, b: Int, out: (Int, Int)->Unit) = out(a, b)
fun returnFun() {
    println("Start of returnFun")
    lambdaFun(10, 20){ a, b ->
        var result = a+b
        if(result >10) { return@lambdaFun }
        println("result: $result")
    } 
}
fun main() {
    returnFun()
}

 

람다함수의 이름이 자동으로 암묵적 라벨로 설정되어 별도의 라벨 지정 작업 없이 lambdaFun라벨을 사용할 수 있습니다.

 

 

4. 라벨의 응용

 

break/continue에 대해서도 라벨을 사용할 수 있습니다.

 

fun labelBreak (){
    println("labelBreak")
    first@for(i in 1..5){
        second@for(j in 1..5){
            if(j == 3){ break@first }
            println("i: $i, j: $j")
        }
        println("After for j")
    }
    println("After for i")
}

 

위와 같이 이중 루프문을 탈출하는데 쓸 수 있으며

 

fun labelContinue() {
    println("labelContinue")
    first@for(i in 1..5){
        second@for(j in 1..5){
            if(j == 3){ continue@first }
            println("i: $i, j: $j")
        }
        println("After for j")
    }
    println("After for i")
}

 

위와 같이 뒤의 작업을 스킵할 떄 사용할 수도 있습니다.

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 21. 생성자  (0) 2019.08.24
[Kotlin] 20. 예외 처리  (0) 2019.08.24
[Kotlin] 18. 반복문  (0) 2019.08.23
[Kotlin] 17. 조건문  (0) 2019.08.23
[Kotlin] 16. 꼬리 재귀 함수  (0) 2019.08.23

References: Do it! 코틀린 프로그래밍

코틀린에서의 반복문에 대해 알아봅니다.

1. for

 

코틀린에서의 for 조건 내부에서는 세미콜론을 사용하지 않습니다.

반복문 for는 다음과 같이 사용합니다

//for(var i = 0; i < 10; i ++)
for(i in 0..9)
//for(var i = 10; i > 0; i --)f
for(i in 10 downTo 1)
//for(var i = 0; i < 10; i = i +2)
for(i in 0..9 step 2)
//for(var i = 10; i > 0; i = i -2)
for(i in 10 downTo 1 step 2)

 

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 20. 예외 처리  (0) 2019.08.24
[Kotlin] 19. 라벨  (0) 2019.08.23
[Kotlin] 17. 조건문  (0) 2019.08.23
[Kotlin] 16. 꼬리 재귀 함수  (0) 2019.08.23
[Kotlin] 15. 확장함수와 중위함수  (0) 2019.08.23

References: Do it! 코틀린 프로그래밍

코틀린에서의 조건문에 대해 알아봅니다.

 

 

1. 범위 연산자: in ..

 

조건문에서 ~이상 ~이하 이런조건은 빈번히 사용됩니다. 아래의 예시를 보겠습니다.

else if(score >= 80.0 && score <= 89.9) { ... ]

80점에서 89.9점까지를 찾는 조건문입니다.

코틀린에선 이러한 포함 여부를 확인할 수 있는 in 연산자와 범위를 지정할 수 있는 .. 연산자를 제공합니다.

 

위의 코드는 다음과 같이 다시 쓸 수 있습니다.

else if(score in 80.0 .. 89.9) { ... }

 

 

 

2. 조건문 when

 

if ... else ... 대신 when 조건문을 사용할 수 있습니다. 다른 언어에서의 switch ... case ... 같은 조건문으로 보입니다.

다음 예시를 통해 확인해 봅시다.

when(x) {
    0, 1, 2, 3 -> println("x는 0~3 사이.")
    5 -> println("x는 5.")
    parseInt(str) -> println("함수의 반환값이 일치함.")
    in 6..10 -> println("x는 6~10 사이.")
    !in 1..10 -> println("x는 1~10 사이에 존재하지 않음.")
    else -> println("x는 다른 무언가")
}

 

parseInt(str)처럼 함수의 반환값이 일치하면 when문에 함수의 반환값을 조건으로 사용할수 도 있습니다.

in 6..10 와 같이 앞서 알아본 범위연산자도 사용할 수 있습니다.

 

when조건문엔 인자를 뺴고 사용할 수도 있습니다. 

이 경우엔 내부 조건에 일치조건 뿐 아니라 다른 조건도 사용할 수 있습니다.

다음 예시를 통해 확인하도록 하겠습니다.

when{
    score >= 90.0 -> grade = 'A'
    score in 80.0..89.9 -> grade = 'B'
    score in 70.0..79.9 -> grade = 'C'
    score < 70.0 -> grade = 'F'
}

인자가 있는 when문과 달리 >=와 같은 조건식을 구성할 수 있습니다.

 

당연하지만 when에 Any클래스도 넣을 수 있습니다.

다양한 자료형의 인자를 받아 각각 다른 결과값을 리턴할 수 도 있습니다.

fun cases(obj: Any){
    when(obj){
        1 -> println("Int($obj)")
        "Hello" -> println("String($obj)")
        is Long -> println("Long($obj)")
        !is String -> println("Not String")
        else -> println("Unknown")
    }
}

 

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 19. 라벨  (0) 2019.08.23
[Kotlin] 18. 반복문  (0) 2019.08.23
[Kotlin] 16. 꼬리 재귀 함수  (0) 2019.08.23
[Kotlin] 15. 확장함수와 중위함수  (0) 2019.08.23
[Kotlin] 14. 인라인 함수  (0) 2019.08.23

References: Do it! 코틀린 프로그래밍

코틀린에서 꼬리재귀함수에 대해 알아봅니다.

 

 

1. 재귀함수

 

꼬리재귀함수를 알아보기전에 재귀함수를 구현해봅시다.

아래는 팩토리얼의 예시입니다.

fun factorial(n: Int): Long = if(n == 1) n.toLong() else n * factorial(n-1)
fun main() {
    val num = 10
    val result: Long = factorial(num)
    println("Factorial: $num -> $result")
}

위의 factorial함수는 10번 호출되며 이 함수의 문맥을 유지하기위해 factorial()함수 스택 메모리의 10배만큼 메모리를 사용하게 됩니다.

만약 num이 큰값으로 설정된다면 실행 환경에 따라 스택 메모리가 부족해지는 문제를 겪을수 도 있습니다.

 

 

2. 꼬리 재귀 함수

 

코틀린에선 이러한 스택 메모리 문제를 방지하기 위해 꼬리 재귀 함수를 도입했습니다.

일반적인 재귀함수는 함수가 호출되고 계산이 이루어지지만 꼬리 재귀 함수에서는 계산을 먼저 하고 함수 호출이 이루어집니다.

따라서 꼬리 재귀 함수를 이용하기 위해선 계산이 먼저 이루어 지도록 함수를 작성해야 합니다.

코드를 다음과 같이 수정합니다.

tailrec fun factorial(n: Int, run: Int =1): Long = if(n==1) run.toLong() else factorial(n-1, run*n)
fun main() {
    val num = 10
    println("Factorial: $num -> ${factorial(num)}")
}

tailrec 키워드를 이용해 꼬리 재귀 함수를 만들었습니다.

factorial(n-1, run*n)는 인자 안에서 팩토리얼이 중간값을 계산하고 호출합니다.

꼬리 재귀 함수는 값을 그때그때 계산하므로 스택 메모리를 낭비하지 않습니다.

 

아래는 피보나치 수열을 일반 재귀 함수로 만든 예시입니다.

import java.math.BigInteger
fun recFibonacci(n: Int, a: BigInteger, b: BigInteger): BigInteger = if(n==0) a else recFibonacci(n-1, a+b, b)
fun main() {
    val num = 25000
    val first: BigInteger = BigInteger("0")
    val second: BigInteger = BigInteger("1")
    println(recFibonacci(num, first, second))
}

실행을 해보면 다음과 같은 결과값을 확인할 수 있습니다.

스택에 계속 쌓아 계산하므로 오버플로우 에러가 발생합니다.

이번엔 꼬리재귀함수로 수정해보겠습니다.

import java.math.BigInteger
tailrec fun fibonacci(n: Int, a: BigInteger, b: BigInteger): BigInteger = if(n==0) a else fibonacci(n-1, b, a+b)
fun main() {
    val num = 25000
    val first: BigInteger = BigInteger("0")
    val second: BigInteger = BigInteger("1")
    println(fibonacci(num, first, second))
}

실행을 해보면 다음과 같은 결과값을 확인할 수 있습니다.

굉장히 긴 값이지만 정상적으로 동작하는것을 확인할 수 있습니다.

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 18. 반복문  (0) 2019.08.23
[Kotlin] 17. 조건문  (0) 2019.08.23
[Kotlin] 15. 확장함수와 중위함수  (0) 2019.08.23
[Kotlin] 14. 인라인 함수  (0) 2019.08.23
[Kotlin] 13. 익명함수  (0) 2019.08.23

jqGrid를 사용하고 있는데 패치 이후부터 컬럼 순서를 변경하면 데이터 표시가 이상하게 된다는 이슈가 왔다.

 

이상하게 꼬였다.

 

위와 같이 헤더 컬럼 이동 후 실제 데이터의 위치가 잘 안맞는 경우 다음과 같은 코드로 확인해보자.

//(grid 선언부의 옵션설정 코드)
....
sortable: function (permutation) { console.log(permutation.join(',')); },
...

sortable에 위와같은 함수를 입력하고 컬럼을 드래그 해보자

 

디버깅 창에 찍힌 결과를 보면 

뭔가 이상한점을 발견할 수 있었다.

colModel에서 문제를 수정후 정상 작동한다.

 

반응형

References: Do it! 코틀린 프로그래밍

코틀린에서의 확장함수와 중위함수에 대해 알아봅니다.

 

 

1. 확장함수.

 

클래스에는 다양한 함수가 정의되어 있습니다. 이미 정의되어 있는 이런 함수들을 클래스의 멤버 메서드라고 합니다.

만약 자기가 원하는 기능을 가진 함수를 클래스에 추가시키고 싶으면 어떻게 할까요?

코틀린에선 이러한 기능을 제공해주며 이를 확장함수라고 합니다.

 

String클래스에 확장함수를 구현하면 String클래스를 쓸 때 사용할 수 있습니다.

만약 Any클래스에 확장함수를 구현해둔다면 모든 클래스에서 사용할 수도 있습니다.

 

String 변수 두개중에 더 긴값을 출력하는 함수를 사용하고자 합니다.

String클래스의 멤버메서드엔 이러한 기능흘 하는 메서드가 없어 새로 확장함수를 추가하려고 합니다.

다음 예시를 확인해봅시다.

fun String.getLongerString(target: String): String = if(this.length > target.length) this else target
fun main(){
    val s1 = "Hello kotlin!"
    val s2 = "Hello!"
    println(s1.getLongerString(s2));
}

String클래스에 getLongerString 확장함수를 추가했습니다. 실행 결과는 다음과 같습니다.

이런 확장함수를 사용하면 기존 클래스의 선언을 수정하지 않아도 쉽게 기능을 확장할 수 있습니다.

 

만약 이미 동일한 멤버함수나 메서드가 존재한다면 항상 확장함수보다 멤버 메서드가 우선적으로 호출됩니다.

 

 

2. 중위함수.

 

중위 표현법은 변수와 변수사이에 함수를 넣어 연산자 처럼 사용하는 것 입니다.

예를들어 multi라는 두 수를 곱하는 함수를 중위 함수로 만들었다면

a multi b

처럼 사용할 수 있는 함수가 중위함수입니다.

 

다음 예시로 확인해 봅시다.

infix fun Int.multi(a: Int): Int = this * a
fun main() {
    var result: Int = 2 multi 4
    println(result)
}

infix 키워드를 이용해 중위 함수를 선언하고 사용했습니다.

일반적인 함수라면 2.multi(4) 와 같은 방식으로 사용할겁니다.

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 17. 조건문  (0) 2019.08.23
[Kotlin] 16. 꼬리 재귀 함수  (0) 2019.08.23
[Kotlin] 14. 인라인 함수  (0) 2019.08.23
[Kotlin] 13. 익명함수  (0) 2019.08.23
[Kotlin] 12. 함수 호출 방법  (0) 2019.08.22

References: Do it! 코틀린 프로그래밍

코틀린에서의 인라인 함수에 대해 알아봅니다.

 

 

1. 인라인함수란?

 

일반 함수가 호출되면 분기가 일어납니다. 따라서 내부적으로 기존 작업 내용을 저장했다가 다시 돌아올 때 복구하는 작업이 필요하며 이러한 작업에 CPU와 메모리에 비용이 발생합니다.

 

인라인 함수는 일반 함수와 달리 인라인 함수의 모든 내용을 함수가 호출되는 곳에 복사합니다.

예를들면

 

fun main(...) {
    ...
    sum()
    ...
    sum()
}
fun sum(){
    //Sum process
}

 

위와 같은 일반함수는 sum()이 호출될 때마다 분기가 일어나 총 2번의 분기가 발생합니다.

만약 sum()이 아래와 같이 인라인 함수로 선언되어 있다면 

inline fun sum(){
    //Sum process
}

 

함수가 실행될 때 sum()함수로 이동되는게 아닌 함수 내용이 복사되어 다음과 같이 수행됩니다.

 

fun main(...) {
    ...
    //Sum process
    ...
    //Sum process
}

 

 

2. 인라인 함수의 제한.

 

인라인 함수의 경우 모든 함수 내용을 복사해 넣기 때문에 함수의 코드가 길면 성능 문제가 발생할 수 있습니다.

다음 예시를 통해 인라인 함수를 제한하는 법을 알아보겠습니다.

 

inline fun sum(out1: ()->Unit, out2: ()->Unit)

 

위의 함수가 인라인으로 실행되면 내부의 두 람다함수도 인라인으로 들어가게됩니다. 

이런함수를 여러번 호출하게되면 코드의 양이 많아지는 문제가 발생합니다.

이런 문제를 해결하기 위해 일부 람다식은 인라인으로 실행되지 않게 하기 위해 noinline 키워드를 사용합니다.

 

inline fun sum(out1: ()->Unit, noinline out2: ()->Unit)

 

 

3. 비지역 반환

 

코틀린에서 익명함수를 종료하기 위해서 return을 사용할 수 있습니다.

그럼 인라인함수에서 사용한 람다식은 어떻게 빠져나올수 있을까요?

인라인 함수내부의 람다식에서는 return문을 사용할 수 있습니다.

다음 예시를 살펴봅시다.

 

inline fun inlineFun(a: Int, out: (Int)->Unit) {
    println("Before calling out()")
    out(a)
    println("After calling out()")
}
fun main(){
    inlineFun(1) {
        println("First call $it")
        return
    }
}

 

위의 예시에서 out(a)는 인라인되어 대체됩니다. 따라서 return을 포함하게 됩니다. 

이로 인해 out(a)에서 return이 포함되버려 println("After calling out()")는 실행되지 않게 됩니다.

이렇게 람다함수에서 return을 만났지만 의도하지 않은 바깥함수인 inlineFun()가 반환 처리되는 것을 비지역 반환이라고 합니다.

 

이런 의도치 않은 비지역 반환을 금지시키기 위해 다음과 같이 코드를 수정합니다.

 

inline fun inlineFun(a: Int, crossinline out: (Int)->Unit) {
    println("Before calling out()")
    nestedFun{ out(a) }
    println("After calling out()")
}
fun nestedFun(body: ()->Unit){
    body()
}
fun main(){
    inlineFun(1) {
        println("First call $it")
        //crossinline에 의해 더이상 return을 사용할 수 없습니다.
    }
}

 

crossinline 은 비지역 반환을 금지해야하는 람다식에 사용됩니다. 

결과를 출력시켜보면 정상적으로 After calling out()이 출력되는걸 확인할 수 있습니다.

 

 

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 16. 꼬리 재귀 함수  (0) 2019.08.23
[Kotlin] 15. 확장함수와 중위함수  (0) 2019.08.23
[Kotlin] 13. 익명함수  (0) 2019.08.23
[Kotlin] 12. 함수 호출 방법  (0) 2019.08.22
[Kotlin] 11. 람다식  (0) 2019.08.22

References: Do it! 코틀린 프로그래밍

코틀린에서의 익명함수에 대해 알아봅니다.

 

1. 익명함수

 

익명함수(Anonymous Function)이란 일반함수지만 함수의 이름지 존재하지 않는 함수입니다.

익명함수의 예시는 다음과 같습니다.

fun(a: Int, b: Int): Int = a + b

위의 익명함수는 변수선언에 그대로 이용할 수 있습니다.

val add: (Int, Int) -> Int = fun(a, b) = a + b
//OR
val add = fun(a: Int, b: Int): Int = a + b

 

 

2. 익명함수를 사용하는 이유.

 

겉보기엔 익명함수는 람다식과 매우 유사해 보입니다.

실제로 익명함수 대신에 람다식을 사용해도 됩니다. 그러면 왜 익명함수를 사용할까요?

람다식에선 return, break, continue와 같은 제어문을 사용하기 어렵기 때문입니다.

함수내 조건에 따라 실행을 중단하고 리턴해야 하는 경우에는 익명함수를 사용하는게 좋습니다.

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 15. 확장함수와 중위함수  (0) 2019.08.23
[Kotlin] 14. 인라인 함수  (0) 2019.08.23
[Kotlin] 12. 함수 호출 방법  (0) 2019.08.22
[Kotlin] 11. 람다식  (0) 2019.08.22
[Kotlin] 10. 함수의 매개변수  (0) 2019.08.21

+ Recent posts