[Kotlin Tutorial] Kotlin 기초 #1 - Chap2. Kotlin basics
참조 : Kotlin in Action
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 를 가질 수 있다. ( { } 안에 내용을 쓸 수 있다 )
'프로그래밍 놀이터 > Kotlin, Coroutine' 카테고리의 다른 글
[Kotlin Tutorial] 함수 정의하고 호출하기 #2 (0) | 2017.08.03 |
---|---|
[Kotlin Tutorial] 함수 정의하고 호출하기 #1 - Chap 3. Defining and calling functions (0) | 2017.08.03 |
[Kotlin Tutorial] Kotlin 기초 #2 - Chap2. Kotlin basics (0) | 2017.07.25 |
[android] Kotlin (코틀린) 이 뭐야? (0) | 2017.07.25 |
[Kotlin Tutorial] Kotlin 소개 - Kotlin : what and why (2) | 2017.07.12 |
댓글