[코틀린] Fast campus 패스트캠퍼스 내돈내산 안드로이드 앱 개발 코틀린편.
문법
인텔리제이에서 코틀린 메인 함수 단축키: psvm
fun main(args : Array<String>){...}
Number 숫자형
// 숫자형 DataType 크기 순으로 선언
var doublev : Double = 110.111 //8
var floatv : Float = 110.1f //4
var longv : Long = 110L //8
var intv : Int = 20 //4
var shortv : Short = 30 //2
var bytev : Byte = 10 //1
println(doublev)
println(floatv)
println(intv)
// 크기변환 후 대입, 메소드 사용
doublev = intv.toDouble()
intv = doublev.toInt()
println("byteStr: "+bytev.toString())
val num ="123".toInt() + 10
println(num)
결과
110.111
110.1
20
byteStr: 10
133
String 문자형
var sLines = """
asdf
dff
123
"""
println(sLines)
var sName= "김이름"
// 문자열 내에 변수 str 치환
var sFormatter = "$sName : sName의 값"
println(sFormatter)
// 파이썬에서 print(f' ... {}') 랑 비슷
var date ="1시"
var sTime = "${ "지금 시각은 "+date }"
println(sTime)
asdf
dff
123
김이름 : sName의 값
지금 시각은 1시
Any 형
// Any형은 동적 타입을 지원한다.
// null 은 ?로 정의
var everybody : Any
everybody = 1111
everybody = "문자열 테스트"
everybody = 222.1011
everybody = 12.00f
if (everybody !is String)
{
if(everybody is Float){
println("float 입니다.")
}
}
<결과>
float 입니다.
// everybody.equals(other = Any?)
println(everybody.equals(12.00f))
true
//문자열 처리시 많이씀
Allprint(1234)
Allprint("Hello")
fun Allprint(a : Any) = println(a.toString())
Hello
// Unit 형은 값이 없음을 정의하는 형
// 넘겨진 파라미터가 1개이면 it 이다.
var pFunc : (String) -> Unit={println(it)}
pFunc("unit unit")
// Nothin형은 미래가 없음을 알리는 형
// TODO("실행하고 종료해버림..")
unit unit
함수
fun funByReturn(s : String) : Any?{
return s
}
fun funByReturn(i:Int , s:String){
println(i.toString()+s)
}
fun funByInline(i : Int, i2 : Int) = i * i2
fun funByNoParam(){
println("funByNoParam")
}
// 고차함수 : 입력 함수로 받고 출력도 함수로
// Unit : void
fun higherFunc(f : () -> Unit){
f()
}
// 함수를 정의한 변수
val funVar = { s : String -> println(s)}
// :: 함수 주소 값을 넘긴다. (* 포인터 개념)
val funcVarType : (String) -> Any? = ::funByReturn
// 메인
fun main()
{
// fun 함수명(변수명 : 데이터크기,...):리턴값(return;}
// 한 줄로 표현가능한 함수는 {} 대신에 = 으로 정의 가능
fun three (n :Int) = 3 * n
println(three(3).toString())
// 함수형 변수의 값 : (변수 정의 -> 코드 구현)
// 함수형 변수의 형 : (입력 정의 -> 리턴 정의)
funByNoParam()
funByReturn(31, " 숫자 입니다.")
println(funByReturn("funByReturn 1 param"))
println(funByInline(31, 10))
funVar("Function Variable 1")
println(funcVarType("Function Variable 2"))
higherFunc( {println("Higer Function")} )
higherFunc { ::funcVarType }
}
제어문
if 문은 java 와 유사, in, is 등과 함께 사용되어 유연하게 사용
반복문 for : for(변수 in 배열 or 범위)
반복문 while : while(조건)
case 문은 Any 타입과 사용,when(변수){조건 -> 실행..)
코틀린은 삼항 연산자가 없다.
조건문 if .. else
fun ifTest(a:Any?)
{
// java 와 유사한 부분 제외
if (a in (0..9)){
println("0~9까지의 숫자: $a")
}else if (a== null){
println("null !")
}else println("else")
}
0~9까지의 숫자: 9
반복문
fun loopTest(count : Int)
{
for(i in (0..count)){
println("i : "+ i)
}
//(0..count).forEach{println("foreach: $it : "+ it)}
var i : Int = 0
while ( i < count) {
i++
println("$i 입니다.(while)")
}
}
i : 0
i : 1
i : 2
i : 3
i : 4
i : 5
i : 6
i : 7
i : 8
1 입니다.(while)
2 입니다.(while)
3 입니다.(while)
4 입니다.(while)
5 입니다.(while)
6 입니다.(while)
7 입니다.(while)
8 입니다.(while)
case문 : when
fun caseTest(o:Any?)
{
when(o)
{
"Test" -> { println("문자: "+o)}
is Int -> { println("숫자: "+o)}
in (0..9) ->{ println("0부터 9까지 숫자 : "+ o)}
else -> { println("error")}
}
}
숫자: 3
var str = " ABCDE"
val result=when(str)
{
is String -> {true}
else -> {false}
}
println(result)
true
레이블
Kotlin 에서 레이블은 매우 중요 : 함수형 언어이기에 리턴되는 곳을 명확히 해야할 필요가 있기 때문이다.
return 반환값
return @레이블 반환값 : 익명함수, 람다함수 구조
break@레이블, continue@레이블 :
break는 반복문 종료후 지정한 레이블로 나간다.
continue 는 다음 라인(뒷 라인) 무시하고 지정한 레이블 이동한다.
// 이런 방식으로 많이 쓰이진 않고
// 어떻게 돌아가는지 이해하는 정도
fun exitLoop()
{
HereToExit@ for(i in 0..2)
{
for(j in 0.. 10)
{
if(j == 5) break@HereToExit
println("i -> $i , j -> $j")
}
println("j loop end")
}
println("i loop end")
}
i -> 0 , j -> 0
i -> 0 , j -> 1
i -> 0 , j -> 2
i -> 0 , j -> 3
i -> 0 , j -> 4
i loop end
break 이라면 내부 for(j ㅑㅜ 0..10) 을 종료하지만
break@레이블 이면 외부 for 을 종료하여
i loop end 가 출력된다.
람다식, 범위 연산자
var lambdaReturn = Exit@{
if(true) {
return@Exit 3
}
1000
// return 1000
}
fun main()
{
(0..10).forEach {
if(it > 3) return@forEach else println(it)
}
}
3
Exit 으로 돌아가 종료한다.
람다 함수나 익명 함수 형식에서 반환 값을 가지고 싶을 때
유용하게 사용하는 것으로 보인다.
//var funVar = { s : String -> return "ss"}
Collection 컬렉션
제네릭 타입 인터페이스
Kotlin에서 Collections는 열거형 데이터 관리하는 데 필수 클래스 집합
read-only : List -> listOf. 항목 데이터 타입 혼합 가능
rw : List -> mutableListOf. 제네릭(<>)으로 반드시 선언
Map : hashMapOf(키 to 값 ..)
Immutable Collection
listOf : read-only
// val lst = listOf <Int> (1,"A",12.00f,false)
val lst = listOf(1,"A",12.00f,true)
println(lst.size)
4
listOf , 제네릭을 쓰지 않으면 모든 타입의 값이 들어갈 수 있다.
* 상수 배열로 쓰인다.
val DAY_LIST = listOf("월", "화", "수")
리스트(List)
저장되는 데이터에 인덱스를 부여한 컬렉션이며 중복된 값 입력 가능
동적으로 리스트를 사용하기 위해서는 리스트 자료형 앞에 뮤터블(Mutable)이라는 접두어가 붙는다.
mutableList, mutableMap, mutableSet
rw : List -> mutableListOf
제네릭(<>)으로 반드시 선언
val lstEdiable = mutableListOf<String>() //class java.util.ArrayList
lstEdiable.add("A")
lstEdiable.add("B")
for(s in lstEdiable)
{
println(s)
}
A
B
Set
셋 (set)
LinkedHashSet, HashSet
중복을 허용하지 않는다.
인덱스로 조회할 수 없고, get 함수도 지원하지 않는다.
var set = mutableSetOf<String>()
set.add("JAN")
set.add("FEB")
set.add("MAR")
set.add("JAN")
기본 타입 : class java.util.LinkedHashSet
To HashSet
val hashset : Set<String> = set.toHashSet()
// class java.util.HashSet
Map
맵(Map) : Map<K, V>
LinkedHasMap, HashMap
키(Key) 와 값(Value)의 쌍으로 입력되는 컬렉션
Keys are unique
var map = mutableMapOf<String, String>()
map.put("key1","value1")
map.put("key2","value2")
map.get("key1")
map.put("key1","수정 value")
println(map.get("key1"))
map.remove("key1")
// 기본 타입 : LinkedHashMap
val numbersMap = mutableMapOf("one" to 1, "two" to 2)
// HasMap
var map = hashMapOf(
"A" to 1,
"B" to 2
)
println(map["A"])
1
예외 처리와 Null 처리 (엘비스(?) , !! , ?. , ?: , as?
var divNumber = 0
try{
}catch (e : Exception){
println(e)
}finally {
println("finally")
}
// 로직으로 막아주면 에러가 안뜬다.
var addNumber : Int? = null
//에러
// var sum = addNumber + 100
// 처리 방법 1
if(addNumber != null){
var sum = addNumber + 100
}
// 처리 방법 2 -> !! (종료) : 널(Null) 값이 안들어 온다는 보증 , 대신 Null 이면 종료
var sum1 = addNumber !! + 100
// 처리 방법 3 -> ?. (실행안됨)
var sum2 = addNumber?.let{
it + 100
}
var name: String? = null // 널값에 대해 안전하게 변수 지정 가능
// 처리 방법 4 -> ?:
var nullStr : String? = null
// addStr라는 변수는 현재 null 이기때문에 결과적으로 name에 "이름" 라는 값이 들어가겠네요.
val name: String = nullStr ?: "이름"
println(name)
// 함수 자체를 return 시키도록 만들 수 도 있습니다.
val nameTwo: String = nullStr ?: return
// addStr 라는 변수는 현재 null 이기때문에 결과적으로 NullPointerException 예외가 발생하겠네요.
val nameThree: String = nullStr ?: throw NullPointerException()
// 처리 방법 5 -> as? , 자료형 변환에 대해 안전하게 변환 할 수 있도록 함
val value: Int = addNumber as? Int ?: 0 //Int 로 변환 할 수 없으므로 0으로 빠지게 됩니다.
댓글