본 글은 코드스피츠90 - 코틀린을 보고 정리한 글입니다.
코틀린은 원시형의 개념을 사용하지 않고 기본형을 정의한다.
basic type - number, Boolean, character, string, array
코드에서는 무조건 래퍼형으로 표현하고, 컴파일러가 컨텍스트와 플랫폼에 따라 래퍼형 또는 원시형 중 유리한 것으로 변환한다.
-> 플랫폼 별 가장 효율적인 번역은 코틀린이 알아서 한다.
Any - 모든 형의 부모
Nothing - 모든 형의 자식이자 제어흐름의 종결을 형으로 표현함
Unit - 없음을 나타내는 형이자 싱글톤 객체
Throwable - 모든 예외의 부모
Function - 함수를 나타내는 형
KClass, KCallable Kproperty, KFunction, KType - 리플렉션 타입
deny list보다 accept list로 짜기
val : 값(value)
var : 변수(variable)
const val : 상수(constant)
val a,b,c (x)
val a (o)
val a:Int = 3
var b:String = "abc"
'...' : Char literal
"..." : String literal
"""...""" : no escaping, newlines (엔터를 쳐도 됨)
[...] : Character Class
[^...] : Exception Character Class
\d : 0,1,2,3,4,5,6,7,8,9
val trim = """[^.\d-+/]"""
except
. 0 1 2 3 4 5 6 7 8 9 - + * /
(...) : capture group
(?:...) : non-capture group
(..|..) : alternative
? : zero or one = {0,1}
+ : one or unlimited = {1,}
fun delegate(a:Int, b:(Int)->Int):Int{
return b(a)
}
delegate(3, {it * 3})
delegate(3){it*3}
# 둘은 같은 표현!
MatchResult.groupValues =
List<String>(전체, 그룹1, 그룹2, 그룹3..)
내부에 N번째 반환할 값을 정의
when(대상){
값1->
값2->{...}
...
else->
}
v:T = when(대상){
값1->T
값2->{
...
T
}
...
else->T
}
val trim = """[^.\d-+*/()]""".toRegex()
fun trim(v:String):String{
return v.replace(trim, "")
}
fun repMtoPM(v:String) = v.replace("-", "+-")
val groupMD = """((?:\+|\+-)?[.\d]+)([*/])((?:\+|\+-)?[.\d]+)""".toRegex()
// 차원을 줄이는 행위는 fold
// findall 은 sequence를 리턴
// Passing Trail Lambdas
fun foldGroup(v:String):Double = groupMD.findAll(v).fold(0.0){ acc, curr->
val (_, left, op, right) = curr.groupValues
val leftValue = left.replace("+", "").toDouble()
val rightValue = right.replace("+", "").toDouble()
val result = when(op){
"*"->leftValue * rightValue
"/"->leftValue / rightValue
else-> throw Throwable("invalid operator $op")
}
acc + result
}
fun calc(v:String) = foldGroup( repMtoPM(trim(v)))