Kotlin 문법 기초

JENNA·2023년 12월 4일
0

자주 사용하는 컨벤션

1) 카멜케이스 camelCase 표기법 - 주로 변수, 메소드의 이름을 지정할 때 사용
fun onCreatActivity()
var intValue: Int

2) 스네이크 snake_case 표기법 - 주로 상수의 이름을 지정할 때 사용(val)
상수일 때, 대문자 사용 {const val HELLO: String = "안녕")
다른 때는 소문자 사용

3) 파스칼케이스 PascalCase 표기법 - 주로 클래스의 이름을 지정할 때 사용
class MainActivity

키보드에서 입력한 숫자(정수)를 불러오는 실습

val dataNumber = readLine()!!.toInt()
val sum = dataNumber + 3
println("입력은 ${dataNumber}인데 3을 더해서 ${sum }이예요!")

변수 선언방식

1) 변수 선언과 동시에 값 넣기
: 입력되는 값으로 타입을 추론할 수 있음
: 값이 입력되는 순간 해당 값의 형태로 변수의 타입이 결정

var 변수명(이름) = 값

(예시)
var myName = "최종호" // 변수명 myName에 문자열 "최종호"를 입력

2) 값으로 초기화하지 않고 선언만 하고 사용하기
: 선언만 할 경우, 반드시 변수명 옆에 콜론(:) 구분자를 붙여서 타입(자료형)을 지정해야 함

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

(예시)
var myAge: Int // 변수명 myAge를 Int 타입으로 선언
myAge = 27     // 숫자 '27'을 입력

-> 이 두가지 예시로 변수는 최초 선언 시에 타입이 결정된다는 것을 예상할 수 있음
-> 변수는 한번 타입을 결정하면 동일한 타입의 값만 담을 수 있음
-> Int 타입의 변수에 문자열 "최종호"입력하면 컴파일 에러 발생

var myAge: Int
myAge = 27

myAge = "홍길동" // (X) 선언했던 값의 타입과 다르기 때문에 입력할 수 없음
myAge = 19     // (O) 선언했던 타입과 같은 숫자(Int)는 입력할 수 있음

읽기 전용 변수 val

val 변수명(이름) = 값

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

val roadName = "국제금융로"        // 미리 지정    
var address = roadName + "8길"   // 필요할 때 조합해서 사용.

문자열 템플릿 ${코드블록}

: 변수가 하나인 경우 $변수 사용 가능하지만, 추가적인 연산식이 필요한 경우 ${코드블록}안에 수식을 입력하는 형태로 사용 가능

"문자열 $변수 문자열"
"문자열 ${변수 + 1} 문자열"

// 가독성을 높이기 위해 변수 하나만 있을 때도 { }를 사용할 수 있습니다.
"문자열 ${변수} 문자열"

자료의 형태, 크기

Long/ 64비트/ 정수
Int/ 32비트/ 정수
Short/ 16비트/ 정수
Byte/ 8비트/ 정수
Double/ 64비트/ 실수(소수)
Float/ 32비트/ 실수(소수) - var floatValue: Float/// floatValue = 3.141592F
Char/ 16비트/ 하나의 문자 - ' '
Boolean/ 8비트/ 논리(참 또는 거짓) - true or flase 중 1개의 값 저장 가능. 조건문.
String/ X/ 문자열

Q. 정수형 변수에 실수형 값을 입력할 수 있나요?

A. 같은 숫자라도 타입이 다르면 기본적으로 입력 X
정수형(Int) 숫자 1/ 실수형(Double) 숫자 1.0은 서로 다른 타입으로 인식
정수형으로 선언된 변수에 실수형 값을 입력할 수 없음
꼭 필요한 경우에는 데이터 타입(자료형)을 변환하는 과정을 거쳐야 입력가능

복합대입연산자

   var num1 = 30
   var num2 = 10

   // 산술연산자와 대입연산자를 따로 사용
   // num1의 값을 10 증가시켜서 40을 만들고 싶다면?
   num1 = num1 + 10
   println("산술, 대입 따로 적용한 결과 ${num1}")

   // 복합대입연산자를 사용
   // num2의 값을 10 증가시켜서 20을 만들고 싶다면?
   num2 += 10
   println("산술, 대입 따로 적용한 결과 ${num2}")
   
   // 뺄셈, 곱셈, 나눗셈, 나머지연산도 동일하게 사용가능
   // 뺄셈: a-=b
   // 곱셈: a*=b
   // 나눗셈: a/=b
   // 나머지: a%=b 

비교연산자

	var baseAge = 20
    var myAge = 20
    var teacherAge = 50
    var babyAge = 7

    var isMyAgePass = myAge == baseAge
    var isTeacherAgePass = teacherAge == baseAge
    var isBabyAgeNoPass = babyAge != baseAge

    println("어서오세요~")
    println("이번 이벤트는 ${baseAge}살만 참여할 수 있습니다!")

    println("================신분증 검사중================")

    println("내 나이는 ${myAge}니까 ${isMyAgePass}다!")
    println("선생님 연세는 ${teacherAge}니까 ${isTeacherAgePass}네요.. 미안해요!")
    println("${babyAge}살은 참여할수 없는게 맞아요! ${isBabyAgeNoPass}")



조건문 if 구조, when구조

// 조건식은 앞서배운 비교 연산자를 사용
// 즉, 조건식 자리에는 true 또는 false의 결과가 들어감
// 조건식이 true일때 중괄호 안의 코드를 실행

if문과 when문은 언제 사용할까?

->if문은 범위가 넓고 값 특정 어려울 때 사용 (연도 데이터..)
->when문은 범위 제한, 값 특정 가능할 때 사용(요일 데이터 7개..)

조건문 if

  • if문 사용 조건

-> if문의 조건식: 비교 연산자(==,<,>)와 논리 연산자(&&,||)를 사용한 조건식만 가능
-> 조건식의 결과는 Boolean 타입인 true, false로 나타남
-> 비교 연산자 (>,<,>=,<=,==,!=) '!='는 두개의 항의 값이 다르면 true
-> 논리 연산자 (&& 논리곱: 두 항이 true일 때 true, || 논리합: 두 항 중 하나의 항이 true일 때 true, ! 부정 다항 연산자: true를 false로 false를 true로 바꿈)

var a = 30
var b = 19
var c = 37
var bigger = a > b && a > c
Log.d("비교 연산자", "a는 b보다 크고, c보다도 큽니다:$bigger") // a는 b보다 크고, c보다도 큽니다.: false
var out = 0
var strike = 3
if (strike > 2) {
    out = out + 1
}

-> Log를 사용해서 변수 out을 출력하면 '1'이 출력

  • if ~ else 문 사용하기
if(조건식) {
	 // 실행할 코드
}

// 둘 중 한개의 코드만 실행됨
if(조건식) {
	// 조건식이 true일때 실행할 코드
} else {
  // 조건식이 false일때 실행할 코드
}
  • if ~ else if ~ else문 사용하기
if (조건식1) {
    // 조건식1의 결과가 참일 경우 실행되는 코드 영역
} else if (조건식 2){
    // 조건식1의 결과가 거짓이고, 조건식2의 결과가 참일 경우 실행되는 코드 영역
} else {
    // 조건식1과 조건식2의 결과가 모두 거짓일 경우 실행되는 코드 영역
}
  • 변수에 직접 if문 사용하기
var a = 5
var b = 3
var bigger = if (a > b) a else b

-> a가 b보다 크므로 변수 bigger에 '5'를 대입

  • 예시) 조건식 = 기말고사 평균점수를 구간별로 나눠서 A,B,C,D 등급 매기기 (입력값)
	var koreanScore = readLine()!!.toInt() // 국어점수 입력
    var englishScore = readLine()!!.toInt() // 영어점수 입력
    var mathScore = readLine()!!.toInt() // 수학점수 입력
    var average = (koreanScore + englishScore + mathScore) / 3
    
    if(average >= 90) {
        println("당신의 등급은 A입니다")
    } else if(average >= 80) {
        println("당신의 등급은 B입니다")
    } else if(average >= 70) {
        println("당신의 등급은 C입니다")
    } else {
        println("당신의 등급은 F입니다")
    }

조건문 when

-> 조건문 when을 이해하기 위해서 다른 언어의 switch문 알아야 됨
-> switch문은 if문의 ==만 사용해서 같은 값인지를 비교하는 조건문
-> kotlin 빼고는 switch라고 사용되고 선택문이라고 불리기도 함

when(변수 또는 상수) {
	 값1 -> {
			// 변수 또는 상수가 값1일때 실행할 코드
	 }
	 값2, 값3 -> {
			// 변수 또는 상수가 값2 또는 값3일때 실행할 코드
	 }
	 in 값3..값9 -> {
			// 변수 또는 상수가 값3~값9사이일 때 실행할 코드
	 }
   else {
			 // 변수 또는 상수가 윗 조건에 해당되지 않을때 실행할 코드
   }
}
  • 예시
package net.flow9.thisiskotlin.basicsyntax

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

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

        var now = 10
        when (now) {
            8 -> {
                Log.d("when", "현재 시간은 8시 입니다.")
            }

            9 -> {
                Log.d("when", "현재 시간은 9시 입니다.")
            }

            else -> { // 위의 모든 조건에 맞지 않으면 else 다음 코드가 실행
                Log.d("when", "현재 시간은 9시가 아닙니다.")
            }
        }
    }
}

/** [로그캣 출력 내용]
현재 시간은 9시가 아닙니다.
*/
  • 특정 값을 비교하는데 결과 처리가 동일하다면 콤마(,)로 구분해서 한번에 비교
 var now = 9
        when (now) {
            8, 9 -> {
                Log.d("when", "현재 시간은 8시 또는 9시 입니다.")
            }
            else -> { // 위의 모든 조건에 맞지 않으면 else 다음 코드가 실행
                Log.d("when", "현재 시간은 9시가 아닙니다.")
            }
        }
    }
}

/** [로그캣 출력 내용]
현재 시간은 8시 또는 9시 입니다.
*/
  • in을 사용해서 범위 값 비교 가능.
  • if문의 비교 연산자 중 <=, >=과 같은 기능을 구현할 수 있음
var ageOfMichael = 19
        when (ageOfMichael) {
            in 10..19 -> {
                Log.d("when", "마이클은 10대 입니다.")
            }

            !in 10..19 -> {
                Log.d("when", "마이클은 10대가 아닙니다.")
            }

            else -> {
                Log.d("when", "마이클의 나이를 알 수 없습니다.")
            }
        }
    }
}

/** [로그캣 출력 내용]
마이클은 10대 입니다.
*/
  • when 다음에 오는 괄호 생략하고 마치 if문처럼 사용 가능
var currentTime = 6
        when {
            currentTime == 5 -> {
                Log.d("when", "현재 시간은 5시 입니다.")
            }

            currentTime > 5 -> {
                Log.d("when", "현재 시간은 시가 넘었습니다.")
            }

            else -> {
                Log.d("when", "현재 시간은 5시 이전입니다.")
            }
        }
    }
}

/** [로그캣 출력 내용]
현재 시간은 5시가 넘었습니다.
*/



반복문 for구조, while구조

//코드를 반복적으로 시행하고자 할 때
//1부터 10까지의 숫자를 Log를 사용하여 출력할 때 반복문 없으면 Log코드를 열 줄 작성해야 됨ㅠㅠ
//반복문은 그 안에서 log코드 한 줄만 작성하면 됨


for문과 while문은 언제 사용할까?

->for문은 특정 횟수만큼 코드를 반복하기 위해 사용
->while문은 특정 조건이 만족할 때 까지 코드를 반복할 때 사용


반복문 for
: 특정 횟수만큼 코드를 반복하기 위해 사용

다음처럼 for 다음의 괄호 ( ) 안에 반복할 범위를 지정하면 for 블록의 코드가 지정한 횟수만큼 반복해서 동작

for (반복할 범위){
    // 실행 코드
}
  • for in ..(온점 2개): 일반적인 형태의 for 반복문
for (변수 in 시작값..종료값){
    // 실행 코드
}
  • ex)
for (index in 1..10){
    Log.d("For", "현재 숫자는 $index")
}

-> 다음은 1부터 10까지 열 번 반복하면서 그 숫자를 변수 index에 먼저 저장하고, 반복하는 횟수만큼 for 블록의 코드를 실행

-> 첫 번째 반복에서는 변수 index에 '1'이 저장되고, 두 번째 반복에서는 index에 '2'가 저장

for에서 until : 마지막 숫자 제외하기

: 시작값과 종료값 사이의 .. (온점 2개) 대신 until을 사용하면 종료값 이전까지만 반복

for (변수 in 시작값 until 종료값){
    // 실행 코드
}
  • 컴퓨터의 인덱스가 항상 0부터 시작 -> 배열의 인덱스를 사용하여 처리하는 코드에서 사용
var array = arrayOf("JAN", "FEB", "MAR", "APR", "MAY", "JUN")
for (index in 0 until array.size){
    Log.d("For", "현재 월은 ${array.get(index)}입니다.")
}

-> 배열의 인덱스가 0부터 시작하기 때문에 배열의 크기는 항상 '마지막 인덱스 + 1의 값'
-> 반복을 할 때 배열의 크기 바로 전까지만 반복해야 됨

for에서 step : 건너뛰기

  • ex) 1부터 100까지 반복하면서 3의 배수만 사용하고 싶다면?
    = step을 사용하면 for 문의 블록을 step 수 만큼 건너뛰어서 실행
for (변수 in 시작값..종료값 step 3){
    // 실행 코드
}

-> 0부터 100까지 반복하며 시작값에서 종료값까지 한 번 반복할 때마다 3씩 증가시켜서 실행

for (index in 0..100 step 3){
    Log.d("For", "현재 숫자는 $index")
}

for에서 downTo : 감소시키기

: downTo를 사용하면 큰 수에서 작은 수로 감소시키면서 반복문을 실행
: 증가할 때와 같이 step을 사용할 수도 있음


반복문 while
: 특정 조건이 만족할 때까지 반복하기 위한 구문
: 반복이 가능한 if 문

while (조건식) {
    // 실행 코드
}

*while문 괄호의 조건식에 true 넣으면 끝없이 동작하는 무한루프에 빠짐
ex)

var a = 1
while (a == 1) {
    Log.d("while", "조건을 만족하면 여기를 출력하세요!")
}

일반적인 while 반복문

: for문과 다르게 증감되는 index있으면 코드에서 직접 처리해야함
: 다음 코드에서는 current변수가 index의 역할을 함

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

-> current가 until에 입력된 12보다 작을 때까지 총 열한 번이 반복됨

while에서 do

: do와 함께 사용하면 while 문의 조건식과 관계없이 do 블록 안의 코드를 한 번 실행

var game = 1
var match = 6
do {
    Log.d("while", "${game}게임 이겼습니다. 우승까지 ${match-game}게임 남았습니다.")
    game +=1
} while (game < match)

while과 do~while의 차이점

: 최초 값이 조건식을 만족하지 않았을 경우
-> while 아무것도 출력되지 x
-> do~while 조건과 상관없이 처음 한번 로그 출력 o

  • while 테스트 -> 아무것도 출력 x
var game = 1
var match = 6

game =6
while (game < match) {
    Log.d("while", "while 테스트입니다.")
    game +=1
}
  • do ~ while 테스트 - 조건 상관 x, 처음 한번 로그 출력 o
var game = 1
var match = 6

game = 6
do {
    Log.d("while", "do ~ while 테스트입니다.")
    game += 1
} while (game < match)

while에서 연산자 이용하기

: 변수와 등호(=) 사이에 산술 연산자인 +, -, *, /가 있으면 변수 자신과 연산한 결과를 대입하라는 의미

(변수 = 변수+1) => (변수 += 1)로 바꿀 수 있음
(변수 = 변수-3) => (변수 -= 3)과 동일

반복문 제어
:반복문 실행 중 특정 조건에서 반복문 벗어나거나, 다음 반복문으로 넘어가기

  • break = 반복문 탈출하기
    :반복문 안에서 break만나면 반복문을 탈출할 수 있음
    :특정 조건에서 무조건 for 블록을 벗어날 때 사용

->다음 코드를 보면 index의 값이 5보다 크면 break가 실행되기 때문에 여섯번째 로그가 찍힌 후에 for 블록을 빠져나감

for (index in 1..10){
    Log.d("break", "현재 index는 $index 입니다.")
    if (index > 5){
        break
    }
}

  • continue = 다음 반복문으로
    :반복문 내에서 continue 만나면 continue 다음 코드는 실행하지 않고 반복문의 처음으로 돌아감

->다음의 예시 코드를 보면 except가 3보다 크고 8보다 작으면 continue 명령으로 로그를 찍지 않고 for 문의 처음으로 돌아가기 때문에 4, 5, 6, 7은 출력되지 않음

for (exceptin 1..10) {
    if (except > 3 && except < 8){
        continue
    }
    Log.d("continue", "현재 index는 $except 입니다.")
}



ex) [for] 내 이름 10번 출력

for(i in 0 until 10) {
	println("${i}번째: 내 이름은 참새")
	i++
}

ex) [for] 전화번호부에서 '참새'가 찾을 때까지 한명식 조회해서 비교

  • break는 가장 가까운 반복문에서 탈출하고 다음 블록으로 넘어가요)
  • continue는 이후의 코드를 실행하지 않아요)
var infos = arrayOf("꿩", "닭", "참새", "오목눈이", "공작새")

for(info in infos) {

	if(info == "참새") {
		println("찾았다 참새!")
		break
	} else {
		continue
	}
}

ex) [for] 배고픈 고양이에게 사료를 10번 먹여주기

var catStatus = false
println("고양이는 매우 배고픕니다..")
println("사료를 10번 먹여주세요")


// 고양이가 현재 배고프니까(false) 사료 배급가능
if(catStatus == false) {
	for(idx in 0..9) {
		println("${idx}번째: 냠냠")
	}
}

// 사료를 10번 준 이후의 상태변화

catStatus = true
if(catStatus == true) {
	println("배부른 고양이입니다")
}

ex) [while] 내 이름 10번 출력

var i = 0

    while(i < 10) {
        println("${i}번째: 내 이름은 참새")
        i++
    }



함수
:코드를 사용할 수 있는 최소 단위

*함수는 fun으로 정의, 반환값이 있는 함수는 내부에서 return으로 값 반환

*'파라미터'=함수 정의할 때 입력값 기술한 것(파라미터 전달, 결과값 돌려받는 방법)

*모든 코드는 함수 안에서 작성, 코드 실행은 함수를 호출하는 것에서 시작

*[프로그램 시작] -- 호출 --> [함수]

함수 - 함수의 정의
:함수는 fun 키워드로 정의하며 값을 입력받아 사용
:입력된 값을 기술한 것을 파라미터(Parameter)라고 함

  • 파라미터와 반환값이 없는 함수도 o -> 둘다 작성하지 x
  • 반환값이 없는 대표적 함수 = Log에 정의되어 있는 d 함수
  • '파라미터 이름 : 타입' = '변수명 : 타입" 둘이 동일하게 사용
fun 함수명(파라미터 이름: 타입): 반환 타입 {
    return 값
}

함수 - 반환값과 입력값이 있는 함수의 정의

ex) Int 타입의 x라는 입력 파라미터를 갖는 함수 square()를 정의함

-square 함수가 호출 -> 입력값 제곱해서 호출한 측으로 반환, 실행 종료

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

함수 - 반환값이 없는 함수의 정의

ex) 반환값 없이 입력값 받아서 Log로 출력하는 함수 printSum()정의

-printSum 함수가 호출되면 결과값을 Log로 출력하고 실행 종료

fun printSum(x: Int, y: Int) {
    Log.d("fun", "x + y = ${x + y}")
}

함수 - 입력값 없이 반환값만 있는 함수의 정의

ex) getPi 함수는 호출한 측으로 3.14를 반환하고 실행이 종료

fun getPi(): Double {
    return 3.14
}

함수의 사용
:함수의 사용은 이름 뒤에 괄호를 붙여서 명령어를 실행하는 형태

-함수는 이름만 호출해서는 실행 x (없으면 '값'처럼 인식)
-반드시 괄호를 붙여야 실행됨

함수의 사용 - 반환값과 입력값이 있는 함수의 호출
:파라미터에 전달할 값 입력, 반환값은 대입 연산자(=)로 변수에 담아 사용

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

함수의 사용 - 반환값이 없는 함수의 호출
: 반환값이 없으면 대입 연산자(=)를 사용 x, 바로 호출해서 실행

printSum(3,5)

함수의 사용 - 입력값이 없는 함수의 호출
:입력값 없다면 괄호만으로 실행하고 결과값 받을 수 있음

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

함수 파라미터의 정의
:함수에 입력되는 파라미터는 변수를 정의하듯 '이름:타입'의 형태로 정의
:여러 개의 파라미터가 정의될 경우 콤마로 구분

  • kotlin에서 함수 파라미터를 통해 입력되는 모든 값은 변하지 않음
  • 따라서 kotlin에서 함수 파라미터는 읽기 전용 키워드 val이 생략된 형태
fun 함수명((val 생략) name1: String, name2: Int, name3: Double) { 실행 코드 }

파라미터의 기본값 정의와 호출
:파라미터는 정의할 때 등호(=)를 사용햇 기본값 설정

fun 함수명(name1: String, name2: Int = 157, name3: Double) { 실행 코드 }

ex)파라미터의 기본값을 가지는 함수를 정의한 예시

  • 정의된 newFunction 함수를 호출할 때 기본값이 없는 첫 번째 파라미터에만 값을 입력하면 두 번째와 세 번째 파라미터에는 설정한 기본값이 자동입력
fun newFunction(name: String, age: Int = 29, weight: Double = 65.5){
    Log.d("fun", "name의 값은 ${name}입니다.")
    Log.d("fun", "age의 값은 ${age}입니다.")
    Log.d("fun", "weight의 값은 ${weight}입니다.")
}

newFunction("Hello")

/** [로그캣 출력 내용]
name의 값은 Hello입니다.
age의 값은 29입니다.
weight의 값은 65.5입니다.
*/

파라미터 이름으로 값 입력

  • 함수에 정의된 파라미터 많으면 입력하는 값의 의미가 명확하지 x 때 있음
  • 이럴경우 순서와 상관없이 정의된 파라미터 이름 지정해서 직접 값 입력
  • 위 코드에서 마지막 행 수정
newFunction("Michael", weight = 67.5)

/** [로그캣 출력 내용]
name의 값은 Michale입니다.
age의 값은 29입니다.
weight의 값은 67.5입니다.
*/

0개의 댓글