본문 바로가기
프로그래밍 놀이터/Kotlin, Coroutine

[Kotlin Tutorial] Kotlin 기초 #1 - Chap2. Kotlin basics

by 돼지왕 왕돼지 2017. 7. 25.
반응형

[Kotlin Tutorial] Kotlin 기초 #1 - Chap2. Kotlin basics


참조 : Kotlin in Action

$, ;, array, as, as type, Basic elements : Functions and variables, blcok as branches, block body, Blocks as branches of “if” and “when”, boolean expression, Break, Classes and Properties, comma, Compiler, constructor, control structure, Declaring enum classes, directories, dot 문법, Double, Easier string formatting: string templates, enum, enum class, enum keyword, enum semicolon, enum with when, enums, equality, Escape, expression, expression and statement, expression body, extends, final variable, func, function, function name, Functions, getter, if expression, if to when, immutable class, immutable reference, implements, import, instanceof, is, Java, java style, java style casting, Keyword, kotlin basics, kotlin hello world, kotlin object, Kotlin source code layout: directories and packages, kotlin tutorial, kotlin 기초, kotlin 코드 구조, loop, mutable reference, Name, new, number literals, objects, operator, package concept, Packages, parameters, primary constructor, println, properties, Public, public getter, public setter, read-only, refactoring, Representing and handling choices: Enums and


2.1. Basic elements : Functions and variables


2.1.1. Hello, world!


-

fun main(args: Array<String>){

    println(“Hello, world!”)

}


fun 는 function 을 정의하는 keyword

type 은 variable 이름 다음에 옴

function이 class 정의 안에 있지 않아도 된다

Array 가 class 이다 ( Java 는 아니징 ) -> Kotlin 에서는 모든 것이 Object 이다

System.out.println 대신 println

; (semicolon) 넣을 필요 없다 ( optional 이라는 의미 )




2.1.2. Functions


-

return type 은 함수 정의 끝에 : (colon) 다음에 온다



-

추가학습)

Expression 은 variable, operator 들로 구성되어 한가지 value 를 생성하는 것이다.

Expression 은 statement 의 일부이다.


val score: Int

score = 90 + 25 // 90 + 25 는 expression, 전체 line 은 statement 이다


val max:Int

max = if ( a > b ) a else b // if 문이 expression 이기 때문에 max 에 assign 가능하다



-

Expression 과 statement.

    Kotlin 에서는 대부분의 loop 를 제외한 control structure 가 expression 이다. ( if 문도 expression 이다 )

    Java 에서 assignment 는 expression 이지만, kotlin 에서는 statement 이다.

    (개념적인 문제인데, expresion 개념만 잘 이해하면 될 듯 하다.)



-

위의 코드는 아래와 같이 쓰일 수도 있다.

fun max(a: Int, b: Int): Int = if (a > b) a else b

= 다음에 오는 내용을 expression body 라고 부른다.



-

위의 코드에서 return type 도 뺄 수 있다. Type 추론(type inference)이 가능하기 때문이다.

Expression body 를 가진 경우에만 return type 을 뺄 수 있다.

그리고 block body 에서는 반드시 return 을 써줘야 한다

fun max(a: Int, b: Int) = if (a > b) a else b




2.1.3. Variables


-

Kotlin 에서 type 이 variable 다음으로 간 이유는 type inference 가 가능한 경우 생략(omit)하기 위함이다.

( 더 Natural 하게 보이기 때문인듯하다 )



-

소숫점은 Double 로 매핑된다.



-

variable 이 initializer 를 가지고 있지 않다면 type 을 반드시 명시해줘야 한다.

val answer: Int // val answer 는 불가능하다, Mutable and immutable variables 에러가 난다

answer = 42



-

val (from value) - Immutable reference. Final variable 이라고 보면 된다.

var (from variable) = Mutable reference.


대부분은 val 로 쓰면 되고 꼭 필요한 경우 var 을 쓰는 습관을 기르면 좋다.



-

주의할 것은 val 로 지정한 변수의 pointer 자체는 변하지 않겠지만, 그 pointing 한 object 의 내용물이 바뀔 수는 있다.

( Java 의 final ArrayList 를 생각해보세용! )




2.1.4. Easier string formatting: string templates


-

fun main(args: Array<String>){

    val name = if (args.size > 0 ) args[0] else “Kotlin”

    println(“Hello, $name!”)

}


$name 과 같은 것을 string templates 이라고 한다.

Compiler 가 내부적으로 알아서 필요시 StringBuilder 를 사용한다


만약 $ 문자가 실제 필요하다면 \$ 를 쓰면 된다.


String template 안에는 ${args[0]} 와 같은 expression 도 가능하다

Expression 형태이면 되기 때문에 당연히 if 문도 들어갈 수 있다




2.2. Classes and Properties


-

아래 문구로 name 을 인자로 받는 constructor 가 있고, getter 가 있는 Immutable class 가 만들어진다… ( 헐.. simple ! )

Value objects 들은 이렇게 간단하게 사용할 수 있다.

그리고 public 도 필요없다. 기본이 public 이기 때문이다.

class Person(val name: String)




2.2.1. Properties


-

class Person{ // default value 가 assign 되지 않은 경우 자동으로 해당 property 들에 대해 constructor가 생성된다

    val name: String, // read-only field, and public getter

    var isMarried: Boolean // writable field, and public getter and setter

}


is 가 prefix 로 되어있는경우 getter 이름은 그대로 쓰인다. 위의 경우 person.isMarried 로 접근가능

val person = Person(“Bob”, true)

println(person.name)

println(person.isMarried)


new 도 필요없고, public accessor 의 경우 getName 대신 dot 문법으로 접근 가능하다

Setter 의 경우도 마찬가지다 person.isMaried = false 로 쓸 수 있다.


심지어 Kotlin 에서 Java 의 getter/setter 접근할 떄도 마찬가지로 dot 문법으로 접근 가능하다




2.2.2. Custom accessors


-

class Rectangle(val height: Int, val width: Int){ // constructor 가 된다 ( primary constructor )

    val isSquare: Boolean

        get() {

            return height == width

        }

        // get() = (height == width) 로 써도 된다

}


당연히 함수로 정의해도 되지만, class 의 property 성격을 가지는 녀석들은 위와 같이 property 와 custom getter 를 제공하는 쪽이 더 선호된다




2.2.3. Kotlin source code layout: directories and packages


-

Kotlin 도 자바와 비슷한 package concept 이 있다.

모든 Kotlin 파일은 맨 앞에 package statement 를 가질 수 있다.

그리고 같은 package 를 가진 파일은 import 없이 바로 쓸 수 있고, 그렇지 않으면 import 해주어야 한다.



-

Kotlin 에서는 class, top level function 모두 import 할 수 있다.



-

Kotlin 은 Java 와 다르게 package 이름과 폴더구조는 상관이 없다.

그러나 Java style 로 가져가는 것이 권장된다. 특히 Kotlin 과 Java 를 함께 쓰는 프로젝트에서는 그렇다.






2.3. Representing and handling choices: Enums and "When"


2.3.1. Declaring enum classes


-

대부분은 Java 보다 적게 쓰는데(코드 길이 기준) enum 만은 class 를 추가로 붙여준다.


enum class Color(val r: Int, val g: Int, val b: Int){

    RED(255, 0, 0), 

    ORANGE(255, 165, 0), 

    YELLOW(255, 255, 0); // 여기는 semicolon 이 꼭 필요하다, 필수는 여기가 유일하다 한다 ㄷㄷ


    fun rgb() = (r*256+g) * 256 + b

}


Kotlin 에서는 enum class 가 reserved keyword 이고 enum 은 keyword 가 아니다 ( Enum class 가 있다. )




2.3.2. Using “when” to deal with enum classes


-

when 도 expression 으로 쓰일 수 있다.

fun getMenemonic(color: Color) = 

    when(color){

        Color.RED -> “Richard”

        Color.ORANGE -> “Of”

        Color.YELLOW -> “York"

    }


when 문은 switch 문과 비슷한 녀석이지만 break 가 필요없다

break 가 없기 때문에 여러개의 condition 을 매핑하려면 이렇게 쓸 수 있다.


fun getWarm(color: Color) = when(color){ // enum class 는 full enum name 이 아니어도 된다

    RED -> “Hot”

    ORANGE, YELLOW -> “warm”

}




2.3.3. Using “when” with arbitrary objects


-

when 이 switch 보다 강력한 또 다른 점은, enum, strings, number literals 뿐만 아니라 모든 objects 에 대해 사용할 수 있다.


fun mix(c1: Color, c2: Color) = when( setOf(c1, c2) ){

    setOf(RED, YELLOW) -> ORANGE

    setOf(YELLOW, ORANGE) -> INDIGO

    else -> throw Exception(“Dirty color”) // else 는 switch 의 default 와 같다

}

// setOf 는 Kotlin api



-

when 은 equality check 이다




2.3.4. Using “when” without an argument


-

fun mixOptimized(c1: Color, c2: Color) = when{

    (c1 == RED && c2 == YELLOW) -> ORANGE

    (c1 == YELLOW && c2 == ORANGE) -> INDIGO

    else -> throw Exception(“Dirty color”)

}


위와 같이 argument 없는 조건문도 사용할 수 있다

이 경우는 branch condition 이 boolean expression 이어야 한다




2.3.5. Smart casts: combining type checks and casts


-

interface Expr // marker interface

class Num(val value: Int) : Expr // : 를 써준것만으로 implements 가 된다

class Sum(val left: Expr, val right: Expr) : Expr



-

fun eval(e: Expr): Int{

    if( e is Num){

        val n = e as Num // java style casting

        return n.value

    }


    If(e is Sum){

        return eval(e.right) + eval(e.left) // e is Sum 으로 이미 casting 이 된 것으로 본다. smartCasting 이라 부른다

    }


    throw IllegalArgumentException(“Unknown expression”)

}


is 로 type check 를 한다 ( Java 의 instanceof 라고 보면 된다 )

Explicit cast 는 as 로 한다



-

Smart cast 는 is check 이후에 variable 이 바뀌지 않는 경우에만 작동한다.

그래서 val 인 것이 좋다.




2.3.6. Refactoring: replacing “if” with “when”


-

Kotlin 에는 ternary operator 가 없다. 대신 if 를 쓰면 된다. If 가 value 를 return 하기 때문이다

fun eval(e: Expr): Int =

    If (e is Num){ // if, else 문만 있는 경우 brace  를 생략할 수 있다

        e.value

    } else if ( e is Sum ){

        eval( e.right ) + eval( e.left )

    } else{

        throw IllegalArgumentException(“Unknown expression”);

    }


when 을 쓰면 더 간단해진다.

fun eval(e: Expr) : Int =

    when{

        e is Num -> e.value

        e is Sum -> eval( e.right ) + eval( e.left )

        else -> throw IllagelArgumentException(“Uknown expression”);

    }



2.3.7. Blocks as branches of “if” and “when”


-

if 와 when 모두 branch 를 가질 수 있다. ( { } 안에 내용을 쓸 수 있다 )





반응형

댓글0