이 포스팅은 고돈호 님의 이것이 안드로이드다 with 코틀린(한빛미디어)을 기반으로 작성되었습니다.

코틀린은 지연 초기화를 사용한다. 이를 통해 앞서서 포스팅한 Nullable의 남용을 방지한다.

일반적으로 Nullable로 선언한 방법은 다음과 같다.

 

1.1 lateinit

class Phone {
    var name: String? = null
    init {
    	name = "iphone"
    }
    fun process() {
       name?.plus("13 pro")
       print("핸드폰 이름의 길이 = ${name?.length}")
       print("모델명 = ${name?.substring(6, 6)}")
   }
}

'?.' 때문에 가독성을 헤치는 경우가 생긴다. 따라서 lateinit를 사용하여 가독성을 향상한다.

class Phone {
    lateinit var name: String
    init {
    	name = "iphone"
    }
    fun process() {
       name.plus("13 pro")
       print("핸드폰 이름의 길이 = ${name.length}")
       print("모델명 = ${name.substring(6, 6)}")
   }
}

전체 예시 코드는 다음과 같다.

package kr.co.ki.function

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        var p = Phone()
        Log.d("nullable", "핸드폰 종류는 ${p.name} 입니다")
        p.process()
    }
}

class Phone {
    var name: String? = null
    init {
        name = "iphone"
    }
    fun process() {
        name = name?.plus("13 pro")
        Log.d("nullable","핸드폰 이름의 길이 = ${name?.length}")
        Log.d("nullable","모델명 = ${name?.substring(6, 12)}")
    }
}

fun String.plus(word: String): String {
    return this + word
}

1.2 lazy

lateinit과 다르게 읽기 전용 변수인 val을 사용하는 지연 초기화이다. 사용법은 다음과 같다.

class Company {
    val person: Person by lazy{ Person() }
    init {
    	// lazy는 선언시에 초기화를 진행하므로 별도의 초기화 과정 필요 X
    }
    fun process() {
        print("person의 이름은 ${person.name}")
    }
}

lazy는 선언 시에 초기화를 하기 때문에 별도의 초기화 과정이 필요 없다.

lazy로 선언된 변수가 최초 호출되는 시점이 by lazy {} 안에 넣은 값으로 초기화가 된다. 즉 위의 코드를 보면 company 클래스가 초기화되더라도 person에 바로 Person()로 초기화되지 않고 process 메서드에서 person.name 이 호출되는 순간 초기화된다.

'안드로이드 앱 개발' 카테고리의 다른 글

8. 코틀린의 null  (0) 2021.12.23
7. 클래스  (0) 2021.12.21
6. 함수  (0) 2021.12.20
5. 반복문  (0) 2021.12.19
4. 배열과 컬렉션  (0) 2021.12.14
이 포스팅은 고돈호 님의 이것이 안드로이드다 with 코틀린(한빛미디어)을 기반으로 작성되었습니다.

코틀린의 경우 다른 언어에서 지원하는 null 이상의 것을 제공한다. 아래의 것들을 통해 알아보자.

 

1. null값 허용 '?'

코틀린은 기본적으로 다른 언어와 달리 기본 변수에 null을 집어넣을 수 없다. 따라서 null을 입력하기 위해서는 '?'를 붙여줘야 한다. 사용법은 다음과 같다.

var variable: String?

예시 코드는 다음과 같다.

var nullVariable: String? // 변수 nullVariable에 null 초기화 허용
nullVariable = null
        
var notNullVariable: String // null 초기화 불가능
notNullVariable = null // null 입력 불가능

2. 함수의 매개변수로 null값 허용

함수 역시 매개변수로 null값을 허용해주기 위해 '?'를 넣어주어야 한다. 예시 코드는 다음과 같다.

fun nullParameter(str: String?) {
    if(str != null) {
        var length2 = str.length
    }
}

3. 함수의 리턴 타입에 null값 허용

return 타입에도 '?'를 붙여 return type을 null을 허용할 수 있다. 예시 코드는 다음과 같다.

fun nullReturn(): String? {
    return null
}

4. Safe call '?.'

'?.'를 이용하여 안전한 호출을 사용할 수 있다. 예시 코드는 다음과 같다.

fun safeCall(str: String?): Int? {
    var resultNull: Int? = str?.length
    return resultNull
}

?. 가 있으면 앞에 변수가 null이면 ?. 뒤를 실행하지 않는다. 즉 str이 null이면 이 예시에서는 길이를 반환하지 않는다. 


5. Null값 대체하기 '?:' - Elvis Operator

fun elvisFunction(str: String?): Int {
    var resultNotNull: Int = str?.length?:0
    return resultNotNull
 }

?: 가 있으면 ?. 앞의 변수가 null일 경우 ?:를 반환한다. 즉 str이 null이면 이 예시에서는 0을 반환한다.

 

'안드로이드 앱 개발' 카테고리의 다른 글

9. 지연 초기화  (0) 2021.12.23
7. 클래스  (0) 2021.12.21
6. 함수  (0) 2021.12.20
5. 반복문  (0) 2021.12.19
4. 배열과 컬렉션  (0) 2021.12.14
이 포스팅은 고돈호 님의 이것이 안드로이드다 with 코틀린(한빛미디어)을 기반으로 작성되었습니다.

1.1 클래스

객체지향어언어와 마찬가지로 코틀린 역시 클래스를 지원한다. 클래스의 기본 구조는 다음과 같다.

class 클래스이름 {
    var 변수명
    fun 함수명(매개변수이름: 매개변수 타입): 반환형 {
    }
}

1.2 클래스의 작성

클래스를 사용하기 위해서 생성자가 필요한데 이 생성자는 프라이머리 생성자와 세컨더리 생성자로 나뉜다. 

 

프라이머리 생성자

프라이머리 생성자는 constructor 키워드를 사용하여 정의하고 조건에 따라 생략을 할 수 있다. 사용방법은 다음과 같다.

class Phone constructor(model: String) {

}

constructor 키워드를 생략할 수 있으며 init 블록에 생성자를 통해 파라미터를 넘길 수 있다. 다만 init가 필요 없다면 파라미터 앞에 val을 넣어 클래스 내부의 전체에서 해당 파라미터를 사용할 수 있다. 다음과 같다.

class Phone(val model: String) {
    fun printModel() {
       print("이름은 ${model} 입니다.")
       }
 }

 

세컨더리 생성자

세컨더리 생성자는 프라이머리 생성자와 다르게 constructor을 클래스 내부로 넣는 것이다. 예시는 다음과 같다.

class Phone {
    constructor (model: String) {
        Log.d("Class", "생성자로 부터 받은 model의 이름은 ${model} 입니다.")
        }
}

세컨더리 생성자는 메소드 오버로딩을 적용하여 여러 개를 중복할 수 있다. 다음과 같다.

class Phone {
    constructor (model: String) {
        Log.d("Class", "생성자로 부터 받은 model의 이름은 ${model} 입니다.")
        }
    constructor (model: Int) {
        Log.d("Class", "생성자로 부터 받은 model의 번호는 $[model} 입니다.")
        }
    constructor (model: String, model2: Int) {
        Log.d("Class", "생성자로 부터 받은 model의 이름은 ${model} 이고 번호는 ${model2} 입니다.")
        }
}

 

Default 생성자

생성자가 없는 경우 Default 생성자가 되며 파라미터가 없는 프라이머리 생성자와 동일하다.


1.3 클래스의 사용

클래스의 사용은 생성자를 호출하며 사용한다. 파라미터 없이 괄호를 붙이면 생성자가 호출되며 init 블록 안의 코드가 실행된다. 세컨더리 생성자는 init 블록이 먼저 실행되며 constructor 블록 안의 코드가 실행이 된다. 다음과 같이 클래스를 호출한 후 생성된 인스턴스를 변수에 담을 수 있다.

var variable = Class()

예시를 통해 사용법을 보면 다음과 같다. (.) dot 연산자를 통해 클래스 내부의 멤버 함수, 멤버 변수에 접근할 수 있다.

class Phone {
    var modelName: String = "Galaxy"
    fun printName() {
        Log.d("Class", "Phone의 이름은 ${modelName} 입니다."_
        }
 }
 
 var phone = Phone()
 phone.modelName = "iphone"
 phone.printName()

1.4 Object

자바의 static과 비슷하게 object를 아용하면 생성자로 인스턴스화 하지 않고 사용할 수 있다. 즉 클래스명에 dot 연산자를 이용하여 멤버 변수 및 멤버 함수에 접근이 가능한 것이다. 예시는 다음과 같다.

Object Phone {
    var modelName: String = "Galaxy"
    fun printName() {
        Log.d("Class", "Phone의 이름은 ${modelName} 입니다."_
        }
 }
 
Phone.modelName = "iphone"
Phone.printName()

단 Object는 한 앱 전체에 한개만 생성될 수 있다.


1.5 Companion Object

companion object를 사용하면 object와 마찬가지로 인스턴스의 생성 없이 사용할 수 있다.

여태까지 로그 출력을 위해 사용했던 Log.d 역시 Log 클래스 안에 object 코드 블록 안에 있기 때문에 바로 클래스명에 dot 연산자를 이용하여 사용할 수 있었다.


1.6 data 클래스

코틀린에서 간단한 값의 저장 용도로 data class를 사용할 수 있다. data 클래스의 형식은 다음과 같다.

data class 클래스 이름(val 파라미터: 파라미터형, val 파라미터2: 파라미터형)

위에서 보이듯 클래스 이름앞에 data class를 붙여야 하고 생성자의 파라미터에 var, val을 사용할 수 있다. 예시는 다음과 같다.

// 정의
data class SimpleDClass(val name: String, val model: Int)
// 생성
var simpleData = SimpleDClass("iphone", 13)

data class에 toString()을 사용하면 클래스의 실제 값을 반환한다.


1.7 클래스의 상속 & 확장

다른 언어에서의 클래스와 동일하게 코틀린의 클래스 역시 상속과 확장을 사용할 수 있다. 상속은 다음과 같이 사용할 수 있다. 부모 클래스의 경우 open 키워드를 사용해야 한다.

open class Parent {

}
class Child: Parent() {

}

부모 클래스의 생성자에 파라미터가 있는 경우 다음과 같이 사용할 수 있다.

open class Parent(value: String) {

}
class Child(value: String): Parent(value) {

}

상속을 사용하면 자식 클래스에서 부모 클래스의 멤버 변수, 멤버 함수를 사용할 수 있다. 예시는 다음과 같다.

open class Phone {
    var model: String = "modelName"
    fun call() {
        Log.d("inheritance", "${model} 으로 전화합니다.")
        }
}

class SmartPhone: Phone() {
    fun smartCall() {
        model = "iphone"
        call()
    }
}

1.8 오버라이딩

오버로딩과 말은 비슷하지만 오버라이딩은 상속에서 메서드를 재정의 하는 것을 의미한다. 만약 위의 예시에서 open class에 있는 call()와 이름이 같게 SmartPhone 클래스에서도 smartCall()를 call()로 변경하면 이것이 바로 오버라이딩 이다. 오버라이드에는 메서드 오버라이드와 프로퍼티 오버라이드가 있으며 이는 각각 다음과 같다.

 

메소드 오버라이드

open class ParentClass {
    open fun opened() {
    }
    fun notOpened() {
    }
}

class ChildClass: ParentClass() {
    override fun opened() {
    }
    override fun notOpened() { // notOpened는 parentClass에서 open이 아니므로 override할 수 없음
    }
}

프로퍼티 오버라이드 

메서드와 마찬가지로 프로퍼티 역시 오버라이드가 가능하며 이 역시 open으로 되어있어야만 오버라이드가 가능하다.

open class ParentClass2 {
    open var opened: String = "I am"
}
class ChildClass2: ParentClass2() {
    override var opened: String = "You are"
}

1.9 익스텐션

코틀린은 미리 만들어져 있는 클래스에 메서드를 넣는 익스텐션이 가능하다. 이때 이 클래스는 자신이 만든 클래스보다는 다른 사람이 작성한 이미 컴파일되어 있는 클래스에 메서드를 추가하기 위한 용도로 사용하는 것이 좋다. 예시는 다음과 같다.

class ExistClass {

    fun A()

    fun B()

                                                                   }

가 있고 이 클래스에 C()를 추가하고 싶으면 ExistClass.c() { } 이렇게 작성한다.

익스텐션의 예시 코드는 다음과 같다.

package kr.co.ki.function

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        testStringExtension()
    }

    fun testStringExtension() {
        var original = "Hello"
        var added = "World!"

        // plus 메서드를 사용하여 문자열 더하기
        Log.d("Extension", "added를 통해 문자열을 더한 값은 ${original.plus(added)} 입니다.")
    }
}

fun String.plus(word: String): String {
    return this + word
}

전체 코드는 다음과 같다.

package kr.co.ki.function

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        //  부모 클래스 직접 호출
        var parent = Phone()
        parent.call()

        // 자식 클래스 호출해서 사용하기
        var child = SmartPhone()
        child.smartCall()

        testStringExtension()
    }

    fun testStringExtension() {
        var original = "Hello"
        var added = " World!"

        // plus 메서드를 사용하여 문자열 더하기
        Log.d("Extension", "added를 통해 문자열을 더한 값은 ${original.plus(added)} 입니다.")
    }
}

// 상속 연습
open class Phone {
    var model: String = "modelName"
    fun call() {
        Log.d("Extension", "${model} 으로 전화합니다.")
    }
}

class SmartPhone: Phone() {
    fun smartCall() {
        model = "iphone"
        call()
    }
}

// 메소드 오버라이드 연습
open class ParentClass {
    open fun opened() {
    }
    fun notOpened() {
    }
}

class ChildClass: ParentClass() {
    override fun opened() {
    }
    //override fun notOpened() { // notOpened는 parentClass에서 open이 아니므로 override할 수 없음
    //}
}

// 프로퍼티 오버라이드 연습
open class ParentClass2 {
    open var opened: String = "I am"
}
class ChildClass2: ParentClass2() {
    override var opened: String = "You are"
}
fun String.plus(word: String): String {
    return this + word
}

'안드로이드 앱 개발' 카테고리의 다른 글

9. 지연 초기화  (0) 2021.12.23
8. 코틀린의 null  (0) 2021.12.23
6. 함수  (0) 2021.12.20
5. 반복문  (0) 2021.12.19
4. 배열과 컬렉션  (0) 2021.12.14
이 포스팅은 고돈호 님의 이것이 안드로이드다 with 코틀린(한빛미디어)을 기반으로 작성되었습니다.

1.1 함수

코틀린 역시 함수가 존재한다. 일반적인 언어에서의 함수와 마찬가지로 매개변수와 return 값이 존재할 수도 존재하지 않을 수도 있다. 함수의 형식은 다음과 같다.

fun 함수이름(파라미터 이름: 파라미터 타입): 반환형 {
    return 값
}

함수의 종류는 각각 다음처럼 존재한다. 예시를 통해 알아보자.

 

1. 반환값과 입력값이 있는 함수

fun square(n: Int): Int {
	return n*n
}

2. 반환값이 없는 함수

fun printMinus(n1: Int, n2: Int) {
	Log.d("fun", "n1 - n2 = ${n1 - n2}")
}

3. 매개변수 없이 반환 값만 있는 함수

fun getPi(): Double {
	return 3.14
}

1.2 함수의 호출

1.1 에서 정의한 함수들을 호출하면서 함수의 호출 방법을 알아보자.

1. 반환값과 입력값이 있는 함수

var result = square(10)
Log.d("fun", "10의 제곱은 ${result}입니다.")

2. 반환값이 없는 함수

Log.d("5 - 3은 ${printMinus(5,3)} 이다.")

3. 매개변수 없이 반환 값만 있는 함수

val PI = getPi()
Log.d("fun", "지름이 10인 원의 넓이는 ${10 * 10 * PI} 입니다.")

1.3 전체 예시 코드

package kr.co.ki.function

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        // 반환값과 입력값이 있는 함수
        var result = square(10)
        Log.d("fun", "10의 제곱은 ${result}입니다.")

        // 반환값이 없는 함수
        printMinus(5, 3)

        // 매개변수 없이 반환값만 있는 함수
        val PI = getPi()
        Log.d("fun", "지름이 10인 원의 넓이는 ${10 * 10 * PI} 입니다.")
    }

    // 반환값과 입력값이 있는 함수
    fun square(n: Int): Int {
        return n*n
    }

    // 반환값이 없는 함수
    fun printMinus(n1: Int, n2: Int) {
        Log.d("fun", "n1 - n2 = ${n1 - n2}")
    }

    // 매개변수 없이 반환값만 있는 함수
    fun getPi(): Double {
        return 3.14
    }
}

 

'안드로이드 앱 개발' 카테고리의 다른 글

8. 코틀린의 null  (0) 2021.12.23
7. 클래스  (0) 2021.12.21
5. 반복문  (0) 2021.12.19
4. 배열과 컬렉션  (0) 2021.12.14
3. 조건문  (0) 2021.12.12
이 포스팅은 고돈호 님의 이것이 안드로이드다 with 코틀린(한빛미디어)을 기반으로 작성되었습니다.

1.1 for문

일반적인 언어들과 마찬가지로 코틀린 역시 반복문을 지닌다. 먼저 for문을 살펴보자. for문은 다음과 같은 형태로 작성한다.

for (인덱스 in 시작 값... 종료 값) {
    
}

for문에 until, downTo 등을 통해 여러 가지 방법을 적용할 수 있다. 다음의 예시 코드를 통해 파악해보자

package kr.co.ki.collectionmap

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        // 1. 일반적인 반복문 10까지
        for (i in 1..10) {
            Log.d("For", "현재 숫자는 ${i}")
        }
        // 2. until로 마지막 숫자 제거
        var array = arrayOf("SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT")
        for (i in 0 until array.size) {
            Log.d("For", "현재 요일은 ${array.get(i)} 입니다.")
        }
        // 3. step을 이용한 건너뛰기
        for (i in 1..10 step 2) {
            Log.d("For", "현재 숫자는 ${i}")
        }
        // 4. down to을 이용한 감소
        for (i in 10 downTo 0) {
            Log.d("For", "현재 숫자는 ${i}")
        }
        // 5. 배열, 컬렉션 사용
        for (day in array) {
            Log.d("For", "현재 요일은 ${day} 입니다.")
        }
    }
}

 출력문은 다음과 같다.

2021-12-19 18:08:01.683 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 1
2021-12-19 18:08:01.683 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 2
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 3
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 4
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 5
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 6
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 7
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 8
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 9
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 10
2021-12-19 18:08:01.684 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 SUN 입니다.
2021-12-19 18:08:01.685 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 MON 입니다.
2021-12-19 18:08:01.685 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 TUE 입니다.
2021-12-19 18:08:01.685 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 WED 입니다.
2021-12-19 18:08:01.685 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 THU 입니다.
2021-12-19 18:08:01.685 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 FRI 입니다.
2021-12-19 18:08:01.685 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 SAT 입니다.
2021-12-19 18:08:01.685 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 1
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 3
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 5
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 7
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 9
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 10
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 9
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 8
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 7
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 6
2021-12-19 18:08:01.686 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 5
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 4
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 3
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 2
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 1
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 숫자는 0
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 SUN 입니다.
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 MON 입니다.
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 TUE 입니다.
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 WED 입니다.
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 THU 입니다.
2021-12-19 18:08:01.687 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 FRI 입니다.
2021-12-19 18:08:01.688 1665-1665/kr.co.ki.collectionmap D/For: 현재 요일은 SAT 입니다.

2.1 while문

For문 이외에도 흔히 반복문으로 사용하는 while 역시 존재한다. For문의 사용법은 다음과 같다.

while (조건식) {

}

while문에는 while, do while문이 존재한다. 이 두 개의 가장 큰 차이점은 do while문은 조건을 만족하지 않으면 실행하지 않는 while문과 달리 무조건 한번 실행한다는 것이다.

package kr.co.ki.collectionmap

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        var current = 1
        var until = 12
        while (current < until) {
            Log.d("while", "현재 값은 ${current} 입니다.")
            current = current + 1
        }

        var cnt = 1
        do {
            Log.d("while", "현재 값은 ${cnt} 입니다.")
            cnt = cnt + 1
        } while (cnt < 1)
    }
}

결과는 다음과 같다. 다음의 그림에서 보이듯이 cnt가 1이고 cnt < 1을 조건으로 있음에도 불고하고 do while문이기 때문에 한 번은 돌아가는 것을 확인할 수 있다.


3.1 break & continue

그 밖에 break, continue문등의 제어문이 있다. 각각 루프문 탈출, 다음 반복문으로 이동하는 역할이다.

'안드로이드 앱 개발' 카테고리의 다른 글

7. 클래스  (0) 2021.12.21
6. 함수  (0) 2021.12.20
4. 배열과 컬렉션  (0) 2021.12.14
3. 조건문  (0) 2021.12.12
2. 변수  (0) 2021.12.12
이 포스팅은 고돈호 님의 이것이 안드로이드다 with 코틀린(한빛미디어)을 기반으로 작성되었습니다.

1.1 배열

배열이란 여러 개의 값을 담을 수 있는 자료형이다. 선언하는 형태는 다음과 같다.

var 변수 = Array(개수)

배열 객체는 자료형에 따라 Int, Double, Char 등의 자료형을 Array뒤에 붙여서 만든다. 각각 다음과 같다.

var IntegerArray = IntArray(5)
var LongArray = LongArray(5)
var CharArray = CharArray(5)
var FloatArray = FloatArray(5)
var DoubleArray = DoubleArray(5)

위의 코드에서 5는 각각 자료형에 따른 공간을 5개 할당하라는 의미이며 이를 표현하면 다음과 같다.

[0] [1] [2] [3] [4]

즉 다른 언어와 마찬가지로 0번째 인덱스부터 시작하며 n-1까지의 공간을 할당하는 것을 알 수 있다.


1.2 문자 배열에 빈 공간 할당하기

String은 기본 타입이 아니므로 배열에서 String을 자료형으로 사용하기 위해서는 다음과 같이 사용해야 한다.

var stringArray = Array(5, {item->""})

1.3 값으로 배열 공간 할당하기

다음처럼 arrayOf 함수를 사용하여 String을 직접 할당할 수도 있다.

var dayArray = arrayOf("SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT")

1.4 배열에 값 입력하기

1. 다른 언어와 유사한 방법

배열명[인덱스] = 값

2. set 함수를 사용한 방법

배열명. set(인덱스, 값)

1.5 배열에 있는 값 꺼내기

배열에 값을 입력하는 것 과 마찬가지로 인덱스로 접근하는 법과 함수를 이용한 방법이 있다.

배열명[인덱스]
배열명.get(인덱스)

ex) 배열 intArray의 다섯 번째 값을 fifthValue에 저장 

var fifthValue = intArray[4] // 인덱스의 시작이 0 이므로
var fifthValue2 = intArray.get(4) // 인덱스의 시작이 0 이므로

1.6 전체 예시 코드

package kr.co.kibeom.array

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        // 1. 기본 타입 배열 선언
        var IntegerArray = IntArray(5)
        var LongArray = LongArray(5)
        var CharArray = CharArray(5)
        var FloatArray = FloatArray(5)
        var DoubleArray = DoubleArray(5)

        // arrayOf 함수를 사용하여 선언과 동시에 값 입력
        var intArray = intArrayOf(1, 2, 3, 4, 5, 6)

        // 2. String형 배열 선언
        var stringArray = Array(10, {item->""})
        // arrayOf 함수를 사용하여 값의 직접 입력을 통한 배열 생성
        var dayArray = arrayOf("SUN", "MON", "TUE", "WED", "THU", "SAT")

        // 3. 앞에서 선언한 배열 IntegerArray 변수에 값 넣기
        // 인덱스를 통해 사용하는 방법
        IntegerArray[0] = 10
        IntegerArray[1] = 20
        IntegerArray[2] = 30
        // set 함수를 사용하는 방법
        IntegerArray.set(3, 40)
        IntegerArray.set(4, 50)

        // 4. 값 변경해보기
        intArray[2] = 30
        intArray.set(3, 40)

        // 5. 배열 값 사용해보기
        var thirdValue = intArray[2] // 인덱스의 시작이 0 이므로
        Log.d("Array", "세번째 intArray의 값은 ${thirdValue} 입니다.")
        var fourthValue = intArray.get(3) // 인덱스의 시작이 0 이므로
        Log.d("Array", "네번째 intArray의 값은 ${fourthValue} 입니다.")

        // 6. 변수에 담지 않고 바로 출력
        Log.d("Array", "첫번째 intArray의 값은 ${intArray[0]} 입니다.")
        Log.d("Array", "두번째 intArray의 값은 ${intArray[1]} 입니다.")
    }
}

2.1 컬렉션

여러 값을 넣을 수 있는 자료형에는 배열과 컬렉션이 존재한다. 이 컬렉션은 동적 배열이라고 불리며 컬렉션의 종류에는 리스트, 맵, 셋이 있다. 각각은 다음과 같다.

 

리스트

저장되는 데이터에 인덱스를 부여한 컬력션이며 중복된 값을 입력할 수 있다. 코틀린에서 동적으로 리스트를 사용하기 위해서는 mutable이라는 접두사를 붙인다.  사용법은 다음과 같다.

 

리스트 생성하기: mutableListOf

위처럼 mutableListOf를 사용하면 동적으로 배열 리스트가 생성된다.

var list = mutableListOf("MON", "TUE", "WED")

리스트에 값 추가하기: add

mutableList.add("THU")

add의 결과는 다음과 같다.

MON TUE WED THU

리스트에서 입력된 값 꺼내기 get 함수

var value = mutable.get(1)

리스트 값 수정하기 set 함수

mutableList.set(1, "값 수정")

리스트에 입력된 값 제거하기 removeAt

mutableList.removeAt(1)

빈 리스트 사용하기

빈 리스트를 사용하는 방법은 다음과 같다.

var 변수명 = mutableListOf<자료형>()
var stringList = mutableListOf<String>()

컬렉션 개수 가져오기: size

size를 통해 컬렉션의 개수를 가져올 수 있다.

mutableList.size

3.1 셋

셋은 우리가 흔히 하는 집합의 구조이며 그에 따라 집합을 허용하지 않는 리스트입니다. 인덱스로 조회할 수 없으며 get 함수를 지원하지 않는다는 특징이 있습니다. 다음과 같이 사용할 수 있습니다.

var set = mutableSetOf<자료형>()

빈 셋으로 초기화하고 값 입력하기

set = mutableSetOf<String>()
set.add("MON")
set.add("TUE")
set.add("WED")
set.add("MON") // 이미 MON이 존재하므로 에러

셋 출력하기

셋은 앞서 말씀드렸듯 인덱스로 조회하는 함수가 없기 때문에 특정 위치의 값을 직접 사용할 수 없다. 따라서 한 번에 출력하기 기능을 사용한다.

Log.d("SET", "Set 전체 출력 = ${set}")

셋 삭제하기

셋은 값이 중복되지 않는 특성 때문에 다른 리스트와 반대로 값을 직접적으로 삭제할 수 있다.

set.remove("MON")

전체 예시 코드

package kr.co.kibeom.collection

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        // 1. 셋 생성하고 값 추가하기
        var set = mutableSetOf<String>()
        set.add("MON")
        set.add("TUE")
        set.add("WED")
        set.add("MON") // 중복된 값 add 불가

        // 2. 전체 데이터 룰력
        Log.d("Collection", "Set 전체 출력 = ${set}")

        // 3. 특정 값 삭제하기
        set.remove("MON")
        Log.d("Collection", "Set 전체 출력 = ${set}")
    }
}

실행결과는 다음과 같다.


4.1 맵

맵은 다른 언어에서도 사용하는 자료구조 이므로 쉽게 알 수 있습니다. 맵은 키와 값으로 이루어져 있으며 해당하는 키에 값이 정해지는 구조입니다. 키, 값을 모두 String으로 정하면 다음과 같습니다.

var map = mutableMapOf<String, String>()

값 추가하기

var map = mutableMapOf<String, String>()
map.put("key1", "MON")
map.put("key2", "TUE")
map.put("key3", "WED")

맵 수정하기

map.put("key2", "FRI")

맵 삭제하기

map.remove("key2")

이 방식으로 그림으로 표현하면 다음과 같다.

key1/MON key2/TUE key3/WED

 

key1/MON key3/WED

전체 예시

 

 package kr.co.kibeom.collection

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        // 맵 생성하기
        var map = mutableMapOf<String, String>()
        // 값 추가
        map.put("key1", "MON")
        map.put("key2", "TUE")
        map.put("key3", "WED")

        // 값 사용
        var variable = map.get("key2")
        Log.d("Collection", "key2의 값은 ${variable} 입니다.")

        // 값 수정
        map.put("key2", "FRI")
        Log.d("Collection", "key2의 값은 ${map.get("key2")} 입니다.")

        // 값 삭제
        map.remove("key2")

        // 삭제한뒤 key2  없으므로 null 출력
        Log.d("Collection", "key2의 값은 ${map.get("key2")} 입니다.")

    }
}

 


5.1 이뮤터블 컬렉션

이뮤터블이란 뮤터블과 반대 즉 변경할 수 없는 리스트를 말한다. 값을 변경할 수 없기 때문에 add, set 등의 함수는 사용할 수 없고 최초로 입력된 값만 사용 가능하다. 즉 수정, 추가, 삭제가 불가능하다.

var list = listOf("1", "2")

'안드로이드 앱 개발' 카테고리의 다른 글

6. 함수  (0) 2021.12.20
5. 반복문  (0) 2021.12.19
3. 조건문  (0) 2021.12.12
2. 변수  (0) 2021.12.12
1. 코틀린의 기본적인 문법  (0) 2021.12.12
이 포스팅은 고돈호 님의 이것이 안드로이드다 with 코틀린(한빛미디어)을 기반으로 작성되었습니다.

1.1 if 문

다음의 예시를 살펴보자

package kr.co.kibeom.basicsyntax

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() { // 새로운 블록의 시작
    override fun onCreate(savedInstanceState: Bundle?) { // 4 칸 공백
        super.onCreate(savedInstanceState) // 이전 4칸의 공백에 추가로 4칸의 공백 즉 8칸 공백
        setContentView(R.layout.activity_main)

        var myNumber = "1, 2, 3, 4, 5, 6"
        var yourNumber = "1, 2, 3, 4, 5, 6"

        if(myNumber == yourNumber) {
            Log.d("checkIf", "myNumber와 yourNumber가 일치합니다.")
        }
        else {
            Log.d("checkIf", "myNumber와 yourNumber가 다릅니다.")
        }
    }
}

myNumber와 yourNumber가 일치하므로 if문이 실행되어 myNumber와 yourNumber가 일치한다는 메시지가 뜨는 것을 확인할 수 있다. 이는 다음의 Log를 통해 알 수 있다.

반대로 일치하지 않다면 else문 안의 Log가 출력이 되는것을 알 수 있다.


1.2 if문 & else if문

이번에는 if문과 else if문의 차이점을 알아보자.

package kr.co.kibeom.controlflow1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        var a = "abc"
        var b = "abcde"
        var c = "abcdefg"

        // if 문 두번 사용
        if (a.length < b.length) {
            Log.d("ControlFlow", "1: a는 b보다 길이가 작습니다.")
        }
        if (a.length < c.length) {
            Log.d("ControlFlow", "1: a는 c보다 길이가 작습니다.")
        }

        // else if문 사용
        if (a.length < b.length) {
            Log.d("ControlFlow", "2: a는 b보다 길이가 작습니다.")
        } else if (a.length < c.length) {
            Log.d("ControlFlow", "2: a는 c보다 길이가 작습니다.")
        }
    }
}

이 코드를 실행하면 다음의 결과가 나오는 것을 확인할 수 있다.

즉 이 결과를 통해 if문의 경우 2개의 if문이 모두 실행된것을 확인할 수 있고 if문 else if문의 경우 if문이 실행되면 else if문이 실행이 안되는 것을 확인할 수 있다.


1.3 그 밖의 if문 활용

if문의 조건식 결과를 변수에 대입할 수 있다. 예시는 다음과 같다.

package kr.co.kibeom.controlflow1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        var goalOfSon = 3
        var goalOfKim = 5

        var winner = if (goalOfSon < goalOfKim) {
            Log.d("SCORE_Result", "Kim이 Son보다 많은 골을 넣었습니다.")
            goalOfKim
        } else {
            Log.d("SCORE_Result", "Son이 Kim보다 많은 골을 넣었습니다.")
            goalOfSon
        }

        Log.d("SCORE_Result", "가장 많은 골을 넣은 사람이 넣은 goal은 ${winner} 입니다.")
    }
}

이를 실행하면 다음의 Log를 확인할 수 있다. 즉 if문의 결과가 변수 winner에 대입이 되는것을 확인할 수 있다.


2.1 When 조건문

when 조건문은 다른 언어에서의 switch문과 비슷하다. 구조는 다음과 같다.

when (파라미터) {
    비교값 -> {
        // 변숫값이 비교 값과 같다면 이 영역이 실행됩니다.
    }
}

이것을 예시로 보면 다음과 같다.

package kr.co.kibeom.controlflow1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        var age = 25
        when (age) {
            23 -> {
                Log.d("when", "나이가 23살 입니다.")
            }
            24 -> {
                Log.d("when", "나이가 24살 입니다.")
            }
            25 -> {
                Log.d("when", "나이가 25살 입니다.")
            }
            26 -> {
                Log.d("when", "나이가 26살 입니다.")
            }
        }
    }
}

실행 결과의 Log를 확인해보면 다음과 같다.

위의 예시에서 콤마를 통해 범위를 비교할 수 있다. 이를 예시로 확인하면 다음과 같다.

package kr.co.kibeom.controlflow1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        var age = 25
        when (age) {
            23, 24 -> {
                Log.d("when", "나이가 23살 또는 24살 입니다.")
            }
            25, 26 -> {
                Log.d("when", "나이가 25살 또는 26살 입니다.")
            }
            26, 27 -> {
                Log.d("when", "나이가 26살 또는 27살 입니다.")
            }
        }
    }
}

역시 실행 후 Log를 확인하면 다음과 같다.

in을 통해 범위값을 비교할 수도 있다. 이는 다음과 같다.

package kr.co.kibeom.controlflow1

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        var age = 25
        when (age) {
            in 10..19 -> {
                Log.d("when", "당신의 나이는 10대 입니다.")
            }
            !in 10..19 -> {
                Log.d("when", "당신의 나이는 10대가 아닙니다.")
            }
        }
    }
}

실행한 후 Log를 확인해보면 다음과 같다.


 

'안드로이드 앱 개발' 카테고리의 다른 글

6. 함수  (0) 2021.12.20
5. 반복문  (0) 2021.12.19
4. 배열과 컬렉션  (0) 2021.12.14
2. 변수  (0) 2021.12.12
1. 코틀린의 기본적인 문법  (0) 2021.12.12
이 포스팅은 고돈호 님의 이것이 안드로이드다 with 코틀린(한빛미디어)을 기반으로 작성되었습니다.

1.1 변수 var

변수(variable)란 값을 임시로 메모리에 저장하고 그 저장공간에 이름을 부여한 것을 의미한다. 변수는 다음 그림과 같이 이름과 값으로 구성된다.

변수의 구성

변수는 변수의 이름앞에 var을 붙여서 선언할 수 있는데 변수 선언과 동시에 값 넣기, 값으로 초기화하지 않고 선언만 하고 사용하기로 나뉠 수 있다. 각각 알아보면 다음과 같다.


1. 변수 선언과 동시에 값 넣기 - 입력되는 값으로 타입을 추론할 수 있다. 

var 변수명(이름) = 값

ex) 변수명 mySubject에 문자열 "안드로이드"를 입력하는 예시

var mySubject = "안드로이드"

2. 값으로 초기화하지 않고 선언만 하고 사용하기 (반드시 변수명 옆에 : 붙여서 자료형 지정하기)

var 변수명 : 타입
변수명 = 값

ex) 변수명 myHeight에를 Int 타입으로 선언하고 다음 줄에서 정수형 180을 입력하는 예시

var myHeight: Int
myHeight = 180

1.2 결론

위의 1, 2 예시를 통해 변수는 최초 선언 시 타입이 결정된다는 것을 알 수 있다. 또한 변수는 한번 타입이 결정되면 결정된 타입과 동일한 타입의 값만 넣을 수 있다. 즉 다시 말하면 위의 mySubject 변수에 180을 넣을 수는 없다.


2.1 데이터 타입

Double : 소수점이 있는 값을 저장할 때 사용

var doubleValue: Double
doubleValue = 3.14

 

Float : Double과 동일하지만 Double에 비해 범위가 작다

var floatValue: Float
floatValue = 3.14F // Double과 구분하기 위해 F를 붙이는 것을 확인할 수 있다.

 

Int : 정수를 저장할 때 사용

var intValue: Int
intValue = 123456789

 

Long : Int보다 큰 범위

var longValue: Long
longValue = 123456789

 

Short, Byte : 두 경우 모두 정숫값을 저장하는 데 사용하지만 Int 보다 작은 범위

var byteValue: Byte = 123
var shortValue: Byte = 123

 

Char : 하나의 글자만 ' '로 감싸 지정

var charValue = 'A'

 

String : 여러 개의 문자를 지정할 수 있음

var stringValue: String = "Android"


Boolean : true, false 둘 중 1개의 값 지정 가능

var boolValue = true

2.2 출력 예시

package kr.co.kibeom.basicsyntax

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

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

        var mySubject = "안드로이드"
        var myHeight: Int
        myHeight = 180
        myHeight += 1
        Log.d("BasicSyntax", "mySubject = $mySubject, myHeight = $myHeight")
    }
}

 

로그 창


3.1 읽기 전용 변수 val

var과 다르기 읽기 전용인 val이 있다. 이 val은 var과 다르게 값을 변경할 수 없다. 선언하는 방법은 다음과 같이 변수와 동일하다.

val 변수명(이름) = 값

변하지 않는 값을 미리 지정해두고 필요에 따라 다른 값과 조합하여 사용할 수 있다.

val familyName = "김"
var fatherName = familyName + "아빠"
var sonName = familyName + "아들"

따라서 val로 지정한 값을 바꾸려 하면 에러가 발생한다.


3.2 const 상수

상수는 주로 기준이 되는 변하지 않는 값을 입력할때 사용, 읽기 전용 변수인 val 앞에 const를 붙여 사용한다.

const val PI = 3.14

val과 변경할 수 없다는 점에서 일치하지만 컴파일 시에 값이 결정되기 때문에 Int, Long과 같은 기본형과 문자열인 String만 입력할 수 있다.


4.1 코딩 컨벤션

코딩시에 지켜야 할 일종의 규칙

 

1. 클래스명 camel case로 작성

class MainActivity // 첫 글자는 대문자 새로운 단어의 첫 글자 대문자

2. 함수명

fun onCreateActivity() // 첫 글자는 소문자, 새로운 단어의 첫 글자만 대문자

3. 변수명

var intValue: Int // 첫 글자는 소문자, 새로운 단어의 첫 글자만 대문자

4. 상수명

const val PI = 3.14 // 모두 대문자
const val PI_VALUE = 3.14 // 두 개의 단어로 이루어져 있다면 단어 사이를 '_' 로 연결

5. 들여쓰기

package kr.co.kibeom.basicsyntax

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() { // 새로운 블록의 시작
    override fun onCreate(savedInstanceState: Bundle?) { // 4 칸 공백
        super.onCreate(savedInstanceState) // 이전 4칸의 공백에 추가로 4칸의 공백 즉 8칸 공백
        setContentView(R.layout.activity_main)
    
        var mySubject = "안드로이드"
        var myHeight: Int
        myHeight = 180
        myHeight += 1
        Log.d("BasicSyntax", "mySubject = $mySubject, myHeight = $myHeight")
    }
}

'안드로이드 앱 개발' 카테고리의 다른 글

6. 함수  (0) 2021.12.20
5. 반복문  (0) 2021.12.19
4. 배열과 컬렉션  (0) 2021.12.14
3. 조건문  (0) 2021.12.12
1. 코틀린의 기본적인 문법  (0) 2021.12.12

+ Recent posts