• if else 문

    • 자바와 유사함.
    var max = a
    if (a < b) max = b
    
    var max:Int
    if(a > b){
    max = a
    }else {
    max = b
    }
    
    • if문이 식으로 사용되는 경우 값을 반환함
    • if식의 경우 반드시 else를 동반해야 함. (반환할 값이 없으면 컴파일 에러..)
    val max = if (a > b) a else b // 3항 연산자랑 비슷하네?
    
    • 3항 연산자가 없음. (위에서 보는거처럼 if가 3항 연산자 역할을 함)
    • if식의 branches들이 블록을 가질 수 있음.
    • 블록의 마지막 구문이 반환 값이 됨.
    val max = if(a > b) {
    print("Choose a")
    a
    }
    else{
    print("Choose b")
    b
    }
    
  • when

    • when문은 switch문을 대체함.
    • when문은 각각의 branches의 조건문이 만족할 때 까지 위에서부터 순차적으로 인자를 비교함.
    when(x){
    	1 -> print("x == 1")
    	2 -> print("x == 2")
    	else -> {   // 1도, 2도 아닐 경우 되는놈. default와 같음.
    		print("x is neither 1 nor 2")
    	}	
    }
    
    • when문이 식으로 사용될 수 있음. 식으로 사용되었을 경우 else문이 필수임. (역시나 값이 설정안되면 컴파일오류..)
    var res = when(x) {
    100 -> "A"
    90 -> "B"
    80 -> "C"
    else -> "F"
    }
    
    // when이 식으로 사용된 경우 컴파일러가 else 문이 없다고 된다는 것을 입증할 수 있으면
    // else를 생략 가능. -> else가 없어도 모든 케이스를 커버 가능한 경우..
    var res = when(x) {
    true -> "맞다"
    false -> "틀리다"
    }
    
    • when이 식으로 사용된 경우 컴파일러가 else 문이 없다고 된다는 것을 입증할 수 있으면 else를 생략 가능.
    • 여러 조건들이 같은 방식으로 처리될 수 있는 경우, branch의 조건문에 콤마 (,) 를 사용하여 표기하면 됨.
    when(x){
    0,1 -> print("x == 0 or x == 1")
    else -> print("Otherwise")
    }
    
    • Branch의 조건문에 함수나 식을 사용할 수 있음.
    when(x) {
       parseInt(x) -> print("s encodes x")
       1 + 3 -> print("4")
       else -> print("s does not encode x")
    }
    
    • range 나 collection에 in이나 !in으로 범위 등을 검사할 수 있음.
    val validNumbers = listOf(3,6,9)
    when(x){
    in validNumbers -> print("x is valid") 
    // x라는 놈이 validNumbers 컬렉션 안에 있는 숫자인지?
    in 1..10 -> print("x is in the range")
    // x라는 놈이 1부터 10 사이에 있는 숫자인지?
    !in 10..20 -> print("x is outside the range")
    // 10 ~ 20범위에 들어있지 않은 숫자인지?
    else -> print("none of the above")
    }
    
    • is나 !is를 사용하여 타입도 검사할 수 있음.
      • 이 때 스마트 캐스트가 적용됨. (타입 캐스팅과 동시에 해당 타입의 함수를 사용할 수 있음)
    fun hasPrefix(x: Any) = when(x) {
    	is String -> x.startsWith("prefix")  // string 타입이면 prefix라는 문자열로 시작해라.
    	else -> false  // 아니면 false
    }
    
    • when은 if - else if 체인을 대체할 수 있음.
    • when에 인자를 입력하지 않으면 논리 연산으로 처리됨. (if, else 이런거 쓸 필요 없을 듯..)
    when{
    x.isOdd() -> print("x is odd")
    x.isEven() -> print("x is even")
    else -> print("x is funny")
    }
    
  • For Loops

    • for문은 iterator를 제공하는 모든 것을 반복할 수 있음.
    for (item in collection)
    	print(item)
    
    • for문의 Body가 블록이 올 수도 있음.
    for (item in collection){
    	print(item.id)
    	print(item.name)
    }
    
    • For문을 지원하는 Iterator의 조건
      • 멤버함수나 확장함수 중에
        • iterator()를 반환하는 것이 있는 경우
          • next()를 가지는 경우
          • hasNext() : Boolean을 가지는 경우
        • 아래의 3개 함수는 operator로 선언되어야 함.(iterator(), hasNext(), next() )
    val myData = MyData()
    for(item in myData) {
    	print(item)
    }
    
    class MyData{
    	operator fun iterator(): MyIterator{
    		return MyIterator()
    	}
    }
    
    class MyIterator {
    	val data = listOf(1,2,3,4,5)
    	var idx = 0
    	
    	operator fun hasNext(): Boolean{
    		return data.size > idx
    	}
    	
    	operator fun next() : Int{
    		return data[idx++]
    	}
    }
    
    • 배열이나 리스트를 반복할 때, index를 이용하고 싶다면 indices를 이용하면 됨.
    val array = arrayOf("가", "나", "다")
    for(i in array.indices) {
    	println("$i: ${array[i\\}")
    }
    
    • index를 이용하고 싶을 때, withIndex()를 이용할 수도 있음.
    val array = arrayOf("가", "나", "다")
    for((index, value) in array.withIndex()) {
    	println("$index: ${value}")
    }
    
  • While Loops

    • while, do-while문은 java와 같음.
    • do-while문에서 body의 지역변수를 do-while 문의 조건문이 참조할 수 있음.
    while(x > 0){
    	x--
    }
    
    do{
    val y = retrieveData()
    }while(y != null) // 안에 있는 y를 그대로 사용함.