본문 바로가기

카테고리 없음

23.12.07

널 세이프티

코틀린은 ?, !!, ?., ?: Null예외로부터 생존가능 하지만 강제로 null이 아니라고하는 !!는 주의!

·        fun main(){

·            var s = Student()

·            s.name = "참새"

·            s.address = "서울"

·            s.displayInfo()

·        }

·         

·        class Student {

·            lateinit var name:String

·            var address:String? = null

·         

·            fun displayInfo() {

·                println("이름은: ${name} 입니다")

·                println("주소는: ${address} 입니다")

·            }

·        }

 

·        String? = null

널이 있어도 정상출력됨

 



fun main(){
//  var data = readLine()!!.toInt()
 
    var inputData = readLine()!!
    var data = inputData.toInt()
    println("Null아닌 값: ${data}")
}

리드라인의 !!가 널이아니다 라는 뜻

var inputData = readLine()!!
    var data = inputData.toInt()

이건 readLine()!!,toInt()를 풀어쓴 것

 

주소를 저장하는 address는 초기값이 null이기때문에 null위협에 놓여있다.



fun main(){
    var s = Student()
    s.name = "참새"
    s.displayAddressLength()
 
    s.address = "서울"
    s.displayInfo()
}
 
class Student {
    lateinit var name:String
    var address:String? = null
 
    fun displayInfo() {
        println("이름은: ${name} 입니다")
        println("주소는: ${address} 입니다")
    }
 
    fun displayAddressLength() {
        println("주소의 길이는: ${address?.length} 입니다")
    }
}

 

println("주소의 길이는: ${address?.length} 입니다")

?. 이건 널이 아니면 제대로 출력, 널이면 널이라고 해라 라는 뜻으로 주소가 null이라 되있으니

주소의 길이는: null 입니다

이름은: 참새 입니다

주소는: 서울 입니다

이렇게 null을 호출. 이러면 널이 나왔다는걸 안전하게 알고 치울수 있다.



println("주소의 길이는: ${address?.length ?: "초기화하세요"} 입니다")

이렇게 바꾸면 초기화 하세요로 바뀜

요약하면,

?: 널을 가질수 있게 만듬

!!: 이건 널이 아니야!하고 강제.

?.: 이건 널이 아니면 제대로 실행되고 널이면 그걸 알림

?: 메시지: 이건 널이 아닐때도 다른 문자열 출력

 

배열이란?

 



fun main(){
    // arrayOf메소드를 호출하면 배열을 리턴해줍니다
// 1,2,3,4,5 각각을 저장한 변수 5개를 배열형태로 arr에 저장합니다
    var arr = arrayOf(1,2,3,4,5)
 
// 배열요소를 모두 출력합니다
    println(Arrays.toString(arr))
 
// 배열의 첫번째 요소에 저장된 값을 출력합니다
// var num1 = 1의 num1과 arr[0]은 동일합니다
// arr[0]은 하나의 변수로 취급할 수 있습니다
// arr은 0~4번방(인덱스)까지 접근할 수 있습니다
    println(arr[0])
}

이건 실행하면 먼저 빨간색 뜨고 안되는걸 창에 누르란대로 alt f4누른 뒤 import눌러야 작동

// var num1 = 1의 num1과 arr[0]은 동일합니다
// arr[0]은 하나의 변수로 취급할 수 있습니다
// arr은 0~4번방(인덱스)까지 접근할 수 있습니다
    println(arr[0])

이 부분이 의미하는건 println(arr[0])하면 위 arrof1의 출력된다는 것

 

배열 쓰는법

fun main() {

    var kors = arrayOf(90, 94, 96)

    for((idx, kor) in kors.withIndex()) {

        println("${idx}번째 국어 점수는 ${kor}입니다")

    }

}

 

이러면 0번째 국어 점수는 90입니다

1번째 국어 점수는 94입니다

2번째 국어 점수는 96입니다 이렇게 나옴

 

map은 자체적으로 k, v를 품고있음


fun
main() {

    // 읽기전용 맵입니다

    // 변수명[] 데이터에 접근할 있습니다

    var scoreInfo1 = mapOf("kor" to 94, "math" to 90, "eng" to 92)

    println(scoreInfo1["kor"])

 

    // 수정가능 맵입니다

    // 변수명[] 데이터에 접근할 있습니다

    var scoreInfo2 = mutableMapOf("kor" to 94, "math" to 90)

    scoreInfo2["eng"] = 92

    println(scoreInfo2["eng"])

 

    // 맵의 키와 값을 동시에 추출해서 사용할 있습니다

    for ((k, v) in scoreInfo2) {

        println("${k} 값은 ${v}입니다")

    }

}

출력시

94

92

kor의 값은 94입니다

math의 값은 90입니다

eng의 값은 92입니다 라고 나옴.

 

맨처음의 92, kor94를 가져와서 94

두번째는 mutableMapOf 데이터를 수정 가능해서 eng라는게 없는데 scoreInfo2["eng"] = 92

를 추가한 결과 추가된 eng를 출력 가능하게 됨

 

마지막은 자기가 알아서 k, v를 찾아서 위에있는걸 추출해서 씀

 

set는 그것이 존재하는지를 찾는다.

fun main() {

    //  읽기전용 Set입니다.

    var birdSet = setOf("", "참새", "비둘기")

 

//  수정가능 Set입니다.

//  var mutableBirdSet = mutableSetOf("", "참새", "비둘기")

//  mutableBirdSet.add("")

//  mutableBirdSet.remove("")

    println("집합의 크기는 ${birdSet.size} 입니다")

 

    var findBird = readLine()!!

 

    if(birdSet.contains(findBird)) {

        println("${findBird} 종류는 존재합니다.")

    } else {

        println("${findBird} 존재하지 않습니다.")

    }

}

그래서 이건 목록에 존재하는지 아닌지 표기하는데 특화되있다.

set는 합집합 같은 집합에 유리

fun main() {

    // 귀여운 새의 집합

    var birdSet = setOf("", "참새", "비둘기", "물오리")

 

    // 날수있는 새의 집합

    var flyBirdSet = setOf("참새", "비둘기", "까치")

 

    // 모든 새의 집합 (합집합)

    var unionBirdSet = birdSet.union(flyBirdSet)

 

    // 귀엽고 날수있는 새의 집합 (교집합)

    var intersectBirdSet = birdSet.intersect(flyBirdSet)

 

    // 귀여운 새들중에서 날수없는 새의 조합 (차집합)

    var subtractBirdSet = birdSet.subtract(flyBirdSet)

 

    println("=====합집합=====")

    println("모든 새의 집합 : ${unionBirdSet}")

 

    println("=====교집합=====")

    println("귀엽고 날수있는 새의 집합 : ${intersectBirdSet}")

 

    println("=====차집합=====")

    println("귀엽고 날수없는 새의 집합 : ${subtractBirdSet}")

}

실행시

=====합집합=====

모든 새의 집합 : [, 참새, 비둘기, 물오리, 까치]

=====교집합=====

귀엽고 날수있는 새의 집합 : [참새, 비둘기]

=====차집합=====

귀엽고 날수없는 새의 집합 : [, 물오리]

 


//
읽기전용 리스트입니다

// 0, 1, 2 인덱스에 접근해서 값을 변경할 없습니다

var scores1 = listOf(1, 2, 3)

 

// 수정가능 리스트입니다

// 0, 1, 2 인덱스에 접근해서 값을 변경할 있습니다

var scores2 = mutableListOf(1, 2, 3)

scores2.set(인덱스, )

 

// 수정가능 리스트입니다

// 0, 1, 2 인덱스에 접근해서 값을 변경할 있습니다

// array 데이터들을 저장하는 ArrayList mutableListOf 동일하게 사용할 있어요

// 저장할 데이터의 자료형을 < > 안에 지정해야 사용할 있어요

var scores3 = ArrayList<자료형>(1, 2, 3)

scores3.set(인덱스, )

ArrayList<자료형>이게 가장 많이 쓰임<>안에 쓸수 있어서

 

 

 

람다식

{매개변수1, 매개변수2... -> 코드 } 이런게 람다식. 편하다고 한다.

세개숫자 평균 내는법

fun add(num1:Int, num2:Int, num3:Int) = (num1+num2+num3)/3

이거나

var add = {num1: Int, num2: Int, num3: Int -> (num1+num2+num3) / 3}

println("평균값은 ${add(10,20,30)}입니다")

 

자료형 변환

  • 숫자 자료형끼리는 to자료형() 메소드를 활용할 수 있어요
  • 문자열을 숫자로 변경할때에는 별도의 메소드가 필요해요

·       
fun
main(){

·            var num1 = 20

·            var num2 = 30.2

·         

·            var num3 = num2.toInt()

·            var num4 = num1.toDouble()

·         

·            var strNum5 = "10"

·            var strNum6 = "10.21"

·         

·            var num5 = Integer.parseInt(strNum5)

·            var num6 = strNum6.toDouble()

·         

·            println("num3: $num3")

·            println("num4: $num4")

·            println("num5: $num5")

·            println("num6: $num6")

·        }

num120인데, 그걸 toDouble()로 실수로 바꾸고 num230.2로 실수인데 그걸 toInt()로 정수로 바꿈 그래서 30.2를 정수로 바꾼 num330, 20을 실수로 바꾼 num420.0

num51010으로, num610.21을 실수로 해서 10.21

 

하나의 메소드가 여러 리턴하게 만들기. pair 두개 triple

fun main() {
    var chicken = Chicken()
    var eggs = chicken.getEggs()
    var listEggs = eggs.toList()
 
//    first, second로 관리
//    var firstEgg = eggs.first
//    var secondEgg = eggs.second
 
    // 리스트로 관리
    var firstEgg = listEggs[0]
    var secondEgg = listEggs[1]
 
    println("달걀의 종류는 ${eggs} 입니다.")
    println("리스트 달걀의 종류는 ${listEggs} 입니다.")
    println("첫번째 달걀의 종류는 ${firstEgg} 입니다.")
    println("두번째 달걀의 종류는 ${secondEgg} 입니다.")
}
 
class Chicken {
    fun getEggs(): Pair<String, String> {
        var eggs = Pair("달걀", "맥반석")
        return eggs
    }
}

답은

달걀의 종류는 (달걀, 맥반석) 입니다.

리스트 달걀의 종류는 [달걀, 맥반석] 입니다.

첫번째 달걀의 종류는 달걀 입니다.

두번째 달걀의 종류는 맥반석 입니다.

이런 이유는 eggPair("달걀", "맥반석") 때문에 달걀,맥반석이 되고

var listEggs = eggs.toList 이것 때문에 lilstegg [달걀, 맥반석]

var firstEgg = listEggs[0]

이것 때문에  리스트에그의 첫번째는 달걀이라 달갈

세컨드에그는 두번째라 맥반석. 트리플은 그냥 하나 더 추가된거라 똑같다.