[Kotlin] Kotlin Study #1

이제일·2023년 7월 23일
0

Kotlin

목록 보기
1/10

Kotlin은 모든 것이 객체다

java에서는 int boolean double과 같은 기본 자료형의 경우 메모리(stack)에 값을 저장하게 된다.
하지만 kotlin에서는 기본 자료형도 Int Boolean Double와 같은 클래스로 지정해야 한다.

// Java
class HelloWorld {
    public static void main(String[] args) {
        System.out.println(1.toString()); // ERROR!
    }
}
// Kotlin
fun main() {
    println(1.toString()) // print: 1
}

이때 코틀린의 숫자 자료형은 컴파일 시 자바의 primitive(int, double, ...) 또는 wrapper(Inteager, ...) 타입으로 자동 변환한다.

  • 대부분의 경우 코틀린의 Int 타입은 자바의 int 타입으로 컴파일된다.
  • 다만, Collection이나 Generic, Nullable(Int?)을 사용하는 경우에는 wrapper로 변경되고 그 외 나머지 경우에는 int로 변경된다.

In Kotlin, everything is an object in the sense that you can call member functions and properties on any variable. Some types can have a special internal representation – for example, numbers, characters and booleans can be represented as primitive values at runtime – but to the user they look like ordinary classes.
참조

Unit, Any, Nothing

  • Unit
    java의 void에 해당하는, 값이 하나뿐인 싱글톤 클래스
  • Any
    java의 Object에 해당하는, Kotlin 클래스 계층 구조의 루트 클래스로 모든 클래스의 상위 클래스
  • Nothing
    모든 클래스의 하위 클래스로 어떠한 값도 포함하지 않는 타입

Nothing은 다음 과 같이 사용된다.

  1. 엘비스 표현식
val nullableValue: String? = null
val value = nullableString ?: throw IllegalStateException()
// Nothing이 모든 타입의 서브 클래스이기 때문에
// value는 항상 String 타입으로 평가된다.
  1. 예외를 던지는 함수의 리턴 타입
fun fail(message: String): Nothing {
    throw IllegalArgumentException(message)
}
// 함수의 반환형으로 쓰이면 리턴이라는 행위 자체를 하지 않음을 의미한다
  1. 타입 추론시
val x = null           // 'x'는 Nothing?의 타입을 가진다
val l = listOf(null)   // 'l'는 List<Nothing?>의 타입을 가진다

Nothing has no instances. You can use Nothing to represent “a value that never exists”
참조


주석 처리

한줄 주석 //과 여러줄 주석 /* ... */을 제공한다.

// This is an end-of-line comment

/* This is a block comment
   on multiple lines. */

문서화 주석 KDoc

KDoc은 Kotlin 코드의 문서화를 위한 언어이고 JavaDoc과 거의 동일하다
가장 큰 차이점은 JavaDoc은 HTML을 사용하고 KDoc은 마크다운도 지원한다.

규칙에 따라 문서 텍스트의 첫 번째 단락(첫 번째 빈 줄까지의 텍스트 블록)은 요소에 대한 요약 설명이고
다음 텍스트는 자세한 설명이다.

모든 블록 태그는 새 줄에서 시작하고 해당 @문자로 시작한다.

KDoc을 사용하여 문서화된 클래스의 예시

/**
 * A group of *members*.
 *
 * This class has no useful logic; it's just a documentation example.
 *
 * @param T the type of a member in this group.
 * @property name the name of this group.
 * @constructor Creates an empty group.
 */
class Group<T>(val name: String) {
    /**
     * Adds a [member] to this group.
     * @return the new size of the group.
     */
    fun add(member: T): Int { ... }
}

블록 태그는 아래와 같다

Tag설명
@paramname class, function 등에 사용되는 변수에 대한 설명 작성
다음과 같이 공백과 대괄호를 사용한 2가지 표현 방식이 있다
ex) @param name description. @param[name] description.
@return함수의 반환값에 대한 설명 작성
@constructorclass의 기본 생성자에 대한 설명 작성
@receiverkotlin extention 함수의 receiver에 대한 설명 작성
@propertyname class 생성자에 있는 properties에 대한 설명 작성
@throwsclass, @exception class 메소드에 의해 발생 가능한 예외에 대한 설명 작성.
모든 예외에 대한 설명을 작성하는 것이 아닌 유용한 정보만 필요에 의해 작성.
@sampleidentifier 요소의 사용방법에 대한 예시 코드를 작성
@seeidentifier 원하는 클래스 혹은 메소드에 대한 링크를 작성
@author문서의 작성자를 명시
@since문서가 작성된 시점의 버전을 작성
@suppress해당 요소를 생성된 문서에서 제외 시키고 싶은 경우 작성

내보내기 Dokka

작성된 코드를 문서처럼 팀에게 공유하고 싶을 때
Dokka를 통해 Swagger처럼 문서화할 수 있다

Android에서의 사용법은 아래와 같다

  1. project의 build gradle에 plugin 추가
plugins {
	...
    
    id 'org.jetbrains.dokka' version '1.6.10'
}
  1. app 모듈에도 플러그인 추가
plugins {
    id 'org.jetbrains.dokka'
}
  1. app 모듈에 dokkaHtml을 설정
android {
   ...
   
    dokkaHtml.configure {
        dokkaSourceSets {
            named("main") {
                noAndroidSdkLink.set(false)
            }
        }
    }
}
  1. 터미널에 명령어 입력
./gradlew dokkaHtml

문자열 처리

  • 문자열 : 두 개의 따옴표 사이에 문자들을 순서대로 나열한 구조.
  • 문자열 템플릿 : 특정 작업 진행 후 출력 시 다시 문자열로 변환하여 출력. $ 기호를 사용함.
val num1 = 100
val num2 = 200 
val str = "test"

println("test : $test") // 문자열 템플릿: 변수 형태
println("sum : ${num1+num2}") // 문자열 템플릿: 표현식 형태

특수 문자

표현출력
\ttab
\bbackspace
\nnew line (LF)
\rcarriage return (CR)
\''
\""
\\ backslash
\$dollar sign
\uunicode, ex) '\uFF00'

Raw 문자열

""" 를 사용해서
일반 문자나 이스케이프 문자, 개행 등을 그대로 문자로 인식해서 처리하는 문자열

val str = """
    test
    \nNewLine
"""
println(str)
/** 출력
	test
	\nNewLine
*/

형식문자

String 메서드에 있는 format을 이용해
java의 printf와 같이 사용할 수 있다.

기호설명
%bboolean
%c문자
%d정수
%e지수
%f실수
%s문자열
%n개행 구분 기호
%h해시코드
%o8진수 정수
%x16진수 정수(기본 16)
%t날짜 또는 시간
val myStr = String.format("%b | %s | %d", false, "Morning", 90)
print(myStr)// false | Morning | 90

print("%b | %s | %d".format(false, "Morning", 90))// false | Morning | 90

연산자 오버로딩

operator 키워드를 이용해 연산자 오버로딩을 구현할 수 있다.

data class Price(val value: Int) {
    operator fun plus(b: Price): Price {
        return Price(value + b.value)
    }
}
val a: Price = Price(10)
val b: Price = Price(50)
val result: Price = a + b // Price(60)

단항 연산자

표현변경되는 함수
+aa.unaryPlus()
-aa.unaryMinus()
!aa.not()
a++a.inc()
a--a.dec()

이항 연산자

표현변경되는 함수
a + ba.plus(b)
a - ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.rem(b)
a..ba.rangeTo(b)

in 연산자

표현변경되는 함수
a in bb.contains(a)
a !in b!b.contains(a)

호출 연산자

표현변경되는 함수
a()a.invoke()
a(i)a.invoke(i)
a(i, j)a.invoke(i, j)
a(i_1, ..., i_n)a.invoke(i_1, ..., i_n)

할당 복합 연산자

표현변경되는 함수
a += ba.plusAssign(b)
a -= ba.minusAssign(b)
a *= ba.timesAssign(b)
a /= ba.divAssign(b)
a %= ba.remAssign(b)

비교 연산자

표현변경되는 함수
a == ba?.equals(b) ?: (b === null)
a != b!(a?.equals(b) ?: (b === null))
a > ba.compareTo(b) > 0
a < ba.compareTo(b) < 0
a >= ba.compareTo(b) >= 0
a <= ba.compareTo(b) <= 0
profile
세상 제일 이제일

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

좋은 정보 얻어갑니다, 감사합니다.

답글 달기