함수와 변수
fun main(args: Array<String>) {
println("Hello World$args")
}
- 클래스 위에 선언 가능
- 변수 선언 , 타입 선언
- System.out.println 표준 라이브러리 함수를 wrapping 한 kotlin 표준 라이브러리임
- 세미 콜론 없어도 됨
fun max(a:Int, b:Int) : Int {
return if(a>b) a else b
}
식(expression)이 본문인 함수
fun max(a:Int,b:Int)=if(a>b) a else b
- 인텔리제이에서는 이 둘의 변환을 지원해 준다 ( Convert to expression body, Convert to block body )
fun max(a:Int, b:Int) = if (a>b) a else b
- 함수 return 타입 생략 가능
- 이유 : 컴파일러가 함수 본문 식을 분석하여 식의 결과 타입을 함수 반환 타입으로 정해줌
=> 타입 추론 ( type inference ) - 식이 본문인 함수만 생략 가능 ( 코틀린 개발 팀의 의도 -> block과 같이 긴 함수는 가독성을 위해 리턴 타입 필요 )
변수
val answer = 42
val answer:Int = 42
var yearsToCompute = 7.5e6 // 7.5 * 10^6
val answer: Int
answer=42
- val : immutable
- var : mutable
- 기본적으로 val을 사용하고 나중에 필요하다면 var로 변경하는 식의 코딩 권장 => 이유 : 이런 코드가 함수형 코드에 가까워짐
val message: String // 초기화 한번만 가능하지만 이렇게 컴파일러가 확인할 수 있으면 아래와 같은 코드 가능
if(canPerformOperation()){
message = "Success"
}
else {
message = "Failed"
}
var answer = 42
answer = "no answer" // error : type mismatch
- 컴파일러는 변수 선언 시점의 초기화 식으로부터 변수의 타입을 추론
- 원시 타입의 변환 방법이 있는데 6.2.3절에 나온다
문자열 템플릿
fun main(args : Array<String>) {
val name = if (args.size>0) args[0] else "Kotlin"
println("Hello, $name" ) // string template 기능
println("Hello, ${args[0]}" )
}
- String template 사용시 주의점 : 한글+영어가 아래와 같이 붙어있으면 unresolved reference에러 발생
-> {}로 감싸는게 좋은 습관
${name}님 반가워요
$name님 반가워요
클래스
class Person(val name: String)
- 데이터만 저장하는 클래스 = 값 객체 ( value object )
- 자바->코틀린으로 변환하면 public visibility modifier가 사라짐을 확인 할 수 있다. 왜냐하면 코틀린의 기본 가시성은 public이다.
코틀린의 기본 가시성이 public인 이유?
코틀린의 클래스는 기본적으로 final이다
https://dzone.com/articles/defending-public-by-default-in-kotlin
프로퍼티
class Person (
val name: String, // 읽기 전용 프로퍼티
var isMarried: Boolean // 쓸 수 있는 프로퍼티
)
val person = Person("Ted", true)
println(person.name) // 코틀린이 자동으로 게터를 호출해 줌
println(person.isMarried)
class Person (
var id = 0
get() = 100
var name = "Ted"
set(value) { name = value }
)
public final void setName(@NotNull String value)
{
Intrinsics.checkParamaeterIsNotNull(value,"value");
this.setName(value);
}
자바로 변환된 코드를 보면 StackOverFlow 에러가 발생한다. 실제로 IntelliJ에서도 알려준다.
field 식별자는 오직 property 접근자에서만 사용 가능하다.
class Person {
var name = "Ted"
set(value) { field = value }
}
커스텀 접근자
- custom getter vs 파라미터가 없는 함수?
- 구현 성능 차이 없음
- 가독성 측면에서 custom getter
class Rectangle(val height:Int, val width:Int) {
val isSquare: Boolean
get() { return height == width } // get()=height==width
}
enum, when
enum class Color {
GREEN, BLUE;
}
enum class Color(
val r: Int, val g: Int, val b: Int
) {
RED(255,0,0);
fun rgb() = (r*256 + g ) * 256 + b
}
println(Color.RED.rgb()) // 255
fun getMnemonic(color: Color) =
when(color) {
Color.Red -> "Richard"
}
fun getWarmth(color: Color) =
when(color) {
Color.Red, Color.YELLOW -> "warm",
Color.BLUE -> "cold"
}
fun getWarmth(color: Color) = when(color) {
RED, YELLOW -> "warm",
BLUE -> "cold"
}
fun mix(c1:Color, c2:Color) {
when(setOf(c1,c2)) {
setOf(RED,YELLOW) -> ORANGE
else -> throw Exception("Dirty Color")
}
}
- 인스턴스 생성 낭비를 막기 위한 인자 없는 when 사용 -> But 가독성이 떨어짐..
fun mixOptimized(c1:Color, c2:Color) =
when {
(c1 == RED && c2 == YELLOW ) -> ORANGE,
(c1 == YELLOW && c2 == BLUE ) -> GREEN
else -> throw Exception("dirty color")
}
스마트 캐스트
/**
* Smart cast
*/
interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr
fun eval(e: Expr): Int {
if (e is Num) {
val n = e as Num
return n.value
}
if (e is Sum) {
return eval(e.right) + eval(e.left) // 캐스팅 명시할 필요 없음 ( IDE 에서 표시해줌ㅎㅎ )
}
throw IllegalArgumentException("Unknown expressions")
}
fun evalRefactor(e: Expr): Int {
when (e) {
is Num -> e.value
is Sum -> eval(e.right) + eval(e.left)
else -> throw IllegalArgumentException("Unknown expressions")
}
}
예외처리
/**
* exception
* - throw 식 활용 ( 6.2.6 )
* - 코틀린 개발자들은 일반 개발자들이 checked exception 을 제대로 쓰지 않다고 판단하여 코틀린에는 checked 안해도 되도록 구현
*/
val number = 10
val percentage =
if (number in 0..100) number
else throw IllegalArgumentException("number must be between 0 and 100 : ${number}")
'Kotlin' 카테고리의 다른 글
Kotlin in Action - 1장. 코틀린이란? 왜 필요한가? (0) | 2020.04.04 |
---|---|
Kotlin in Action 11장 : DSL 만들기 (0) | 2020.04.03 |
Kotlin In Action 7장. 연산자 오버로딩과 기타 관례 (0) | 2020.04.02 |
Kotlin In Action - 5장. 람다로 프로그래밍 (0) | 2020.03.29 |
Kotlin In Action - 3장.함수 정의와 호출 (0) | 2020.03.29 |