일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 일론머스크
- 2차 비상계엄
- 홈플러스
- 시그니처
- 1203계엄령
- 원달러환율
- 원스휴먼 황금양
- 원스휴먼 황금양털파밍
- 레시피 파밍
- 원스휴먼 레시피
- 믹스커피
- 국방부
- 원스휴먼 레시피 파밍
- 원스휴먼 쿠폰
- 홈플러스 시그니처 모카골드믹스커피
- 원스휴먼 요리
- 커피추천
- 원스휴먼 먹이
- 유광버섯 통조림
- 2차계엄
- 계엄령 외신반응
- 믹스커피추천
- 원스휴먼 동물
- 계엄령
- 원스휴먼 황금양 구하기
- 원스휴먼 사료
- 원스휴먼 스타크롬
- 비상계엄령
- 윤석열
- Today
- Total
0101011001010111
Kotlin_4-5 널 세이프티 ? !! ?. ?: 본문
널 세이프티는,
코틀린의 Null 안정성을 향상시켜줄 수 있어요.
Null예외는 프로그램의 가용성을 저하시키는 치명적인 오류에요.
ㄴNull예외의 의미가 뭐지 ?
예외는, 프로그램이 실행되다가 런오류로 중단되고 종료되는 현상을 말하고,
그럼 null예외는 null때문에 예외 현상이 생긴다는 건가?
답 : 내가 생각하는게 맞다함!!! 오케이!!!! 저 뜻이 맞구나!!!!
자 Null예외가 발생하면 프로그램이 꺼져버립니다.(사용하다 종료되는 것 만큼 안좋은 행위는 없겠죠?)
코틀린은 Null예외로 부터 안전한 설계를 위해 자료형에 Null 여부를 명시할 수 있어요.
- Null 여부 명시 : null을 가질수 있다 없다를 표기하는 행위 // 그렇기 때문에 Null예외에서 안전하다라고 말할 수 있게 되는 거죠.(뭐보다? JAVA보다요 ^_^;)
Null예외로 부터 안전한 설계를 위한 다양한 키워드들을 지원합니다.
코틀린은, ? , !! , ?. , ?: 로 Null예외로 부터 살아남으려 한다.
BUT!!!! 강제로 null이 아니라고 하는 의미의 !!는 최대한 사용을 지양해주세요!!( 최대한 사용하지말기)
ㄴ ㅋㅋ 정말!! 자신있는거 아니면 사용 하지말기 ^ㅁ^
다양한 널 세이프티 값 검색해보기▼
앨비스 연산자
앨비스 연산자는 ?: 으로 표현하고, ?: 의 왼쪽 객체가 non-null이면 그 객체의 값이 리턴되고,
null이라면 ?: 오른쪽 값을 리턴합니다.
그러니까,
5 ?: 9 면, 왼쪽 객체가 non-null(널이아님) 이니까 5가 리턴되고,
null ?: 9 이면 왼쪽값이 null이어서 9를 리턴한다는 거
?
코틀린에서 '?'는 nullable (널허용) 타입을 지정하는데 사용되는 기호입니다.
기본적으로 Kotlin에서는 모든 타입이 non-nullable 입니다. ( 즉, 변수에 null값을 할당X)
그러나 경우에 따라선 null값이 허용되는 것이 필요할 수 있음.
이런 겅우 '?'를 사용하여 타입을 nullable로 선언 가능.
예제▼
var a: String = "Hello World"
a = null
▲위와 같은 코드가 있다고 생각해보자.
문제는 코틀린 기본값이 : non-nallable (null값 허용안됨) 이므로, 변수 a가 null 이기 때문에 오류가 발생할 수 있다.
이럴때는 아래코드처럼▼
var a: String? = "Hello World"
a = null // This line is now valid
String 에 ?를 붙여 nullable(널값허용) 해주면 문제가 해결된다!
?는 nullable이므로!!!
안전 호출 연산자(safe call operator / Safe-calls)
이 연산자는 해당 객체가 null이 아닐 경우에만 메서드를 호출하거나 필드에 접근합니다.
예제▼
var a: String? = "Hello World"
println(a?.length)
여기서 변수 a는 : null일수 있는 String(문자열)타입 입니다.
ㄴ String? ?는 nullable을 뜻하므로
따라서 ?.(안전호출연산자 safe call operator)를 사용하여 a가 null이 아닌 경우에만 length 속성에 접근합니다.
ㄴ뭔말이야 ㅡㅠ 아~ println(a?.length)니까, a가 null이 아닐경우에만 저 프린트를 한다는 말이지
근데, a?.length라고 표현하면 그냥 nullable을 표시하는 ?를 쓰고 싶은데, 그 연결해주는 연산자가 ( . ) 점이니까
그럼 a?.length라고 써야하는데 이게 ?.(safe call operator)인지, 아니면 ?(nullable)인지 어떻게 구분해 ?
아? 이해가 되었다.
?는 a를 선언할때 사용하는 거니까 위와같은 println(a?.length) 막 이런 불러오는거에 조합에서 쓸 이유는 없지!
- 시원 -
그러니까 저 불러오는거에서는 a?.length가 있으면 nallable이 아니라 safe call operator 인거지!!
(+고오급 지식 추가)안전 호출 연산자(safe call operator)은 체이닝 할 수 도 있다!!!!
멋져.. 추가 개념까지 공부하는 나의모습.ㅋㅋㅋㅋㅋㅋ 쫌 초보 탈출했나 후후.
자 다음 예제를 살펴보자 ▼
var a: Person? = getPerson() // This might return a Person object or null
println(a?.address?.city) // This will print the city only if a and a.address are not null
이런 코드가 있다고 해봐,
보자마자 난 궁금했지.
println(a?.address?.city)
이부분이!!!!!!!!!
물음표 많이 들어가니까 갑자기 현타오지만
다시 복기하자 안전 호출 연산자 safe call operator는 뭐라고 ?!
★이 연산자는 해당 객체가 null이 아닐 경우에만 메서드를 호출하거나 필드에 접근합니다.★
맞아.
그렇기 때문에 ?. 이 2개든 100개든 두렵지 않아.
이건 ?.이 붙은 모든 조건이 null이 아니어야 'city'에 접근할 수 있어!!!
non-null assertion operator (null이 아님을 단언하는 연산자)
- 이건 값이 null이 아닌 것을 확신/단언 하는 연산자이다.
ㄴ 조심해서 써야한다. 100% 확신하는 연산자라.
!! 연산자를 사용하면 nullable한 객체에 대해 null이 아님을 단언합니다.
즉 'a!!'라는 코드는 'a'가 null이 아니라고 확신하고 non-null 타입으로 처리하겠다는 의미입니다.
그러나 만약 'a'가 실제로 null인 경우에는 NullPointerException이 발생합니다.
var a: String? = null
println(a!!.length)
▲ 위의 코드는 실행되지 않고 NullPointerException을 발생시킵니다.
왜냐면 a는 null이지만 !! 연산자를 사용하여 a를 non-null로 취급하려고 시도했기 때문입니다.
따라서, !! 연산자는 null이 아님을 확실히 알고 있는 경우에만 사용해야합니다.
또한 이 연산자를 남용하면 NullPointerException을 발생시킬 수 있으므로 주의해야 합니다.
Kotlin의 주요 목표 중 하나는 NullPointerException을 최소화하는 것이므로. 가능하면 `?.` 연산자나 `?:`(elvis operator)등을 사용하여 null을 안전하게 처리하는것이 좋습니다.
예시 ▼
주소를 저장하는 address변수는 null을 저장할 수 있다고 String?으로 선언해요
null을 저장하지 않고 설계하려면 lateinit var로 대체할수 있어요. // 저번시간에 lateinit은 배웠다!! 그.. 변수 지연초기화!
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} 입니다")
}
}
lateinit var name:String
name은 lateinit var (변수지연초기화)로 선언되었고, 문자열이다.
address는 물음표(?)를 붙여서 nullable (널 허용) 으로 해줬습니다.
address의 값은 null이죠 ?
처음에 null을 가졌지만, address라는 거에 서울로 바꿔준거고
s.displayInfo()하면 이름과 주소를 정상적으로 출력 하게 됩니다.
!! 의 예제
!! : 해당값은 null이 아님을 100% 단언 하는 연산자
fun main(){
// var data = readLine()!!.toInt()
var inputData = readLine()!!
var data = inputData.toInt()
println("Null아닌 값: ${data}")
}
ㄴ 이것 같은 경우에는 저희가 많이 사용했던 키워드에요.
이 변수/상수 값은 반드시 null이 아니야 라고 해주는거죠
readLine()!!
readLine이라는 메서드를 호출() 하면 어떤 리턴을 해주는데, 그 값이 반드시 null이 아니야 라고 !! 를 붙여준거에요
var inputData = readLine()!!
그것을 변수 inputData에 넣어주고
var data = inputData.toInt()
(다음줄) inputData는 당연히 null이 아니니까 null체크를 할 필요없이 바로 toInt라는 걸 실행()하고
println("Null아닌 값: ${data}")
null이 아닌 값인 데이터를 출력 할 수 있게 되는 겁니다.
지금 설명한건 var data = readLine()!!.toInt() << 요 한줄로 끝나는 걸 풀어서 설명한 것이다.
이렇게 한줄로 가능한 이유는
원래 위에 설명했듯,
var inputData = readLine()!! //원래는 여기서 끊고
var data = inputData.toInt() //이렇게 다음이 나와야하지만,
var data = readLine()!!.toInt() //이게 널이 아니라고 했으니 바로 toInt()를 써줄수 있었던 것이다.
?.키워드로 Null인지 확인하고 Null이 아닐때만 참조하는 메소드를 실행하도록 작성해요
var address:String? = null
주소를 저장하는 address는 초기값이 null이기 대문에 null위협에 놓여있어요.
Null이 아님을 보장해야하는데 강제로 !!를 사용하는 것은 현 상황에 바람직 하지 않아요.
?. 은 안전 호출연산자(safe-calls)라고 해요
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} 입니다")
}
}
자, 메인에 있는 순서대로 실행이 된다.
var s = Student()
먼저 s라는 변수는 Student()를 실행하는거라고 알려주고.
s.name = "참새"
s.displayAddressLength()
s //스튜던트 실행시
.name 은 참새이다.
이름값 들어갔고,
이제 s.displayAddressLength()를 위의 값으로 실행시킴.
여기서
println("주소의 길이는: ${address?.length} 입니다") // 이름은 출력시 필요하지 않은 함수이다.
var address:String? = null
address값은 null이기 때문에 주소는 null인데,
?. 를 썼을 때, null이면 그냥 종료되는 것이 아니라 ,
null일경우 null로 출력이 되게 된다.
그렇기 때문에 위와 같은 값은 여기서 나온거다.
자, 다음 main에서 실행할 구문은
s.address = "서울"
s.displayInfo()
이다.
이번엔 address값을 서울로 받았고,
s.displayInfo()
s = student클래스를 토대로 // displayInfo() 함수를 실행한다.
fun displayInfo() {
println("이름은: ${name} 입니다")
println("주소는: ${address} 입니다")
}
출력하게 되면
아래 두줄에 해당 하는 값이 아랫줄 값이다.
자, 근데 ?. 안전 호출연산자(safe-calls)로 실행을 했는데,
?. 에서 null일 경우 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대신에)
null 대신에 초기화 하세요 라고 나온거에요
앨비스 연산자
앨비스 연산자는 ?: 으로 표현하고, ?: 의 왼쪽 객체가 non-null이면 그 객체의 값이 리턴되고,
null이라면 ?: 오른쪽 값을 리턴합니다.
널 세이프티는 코틀린의 가장 큰 장점중 하나에요.
그중에 null을 가질 수 있게하는 `?` 키워드
null이 아님을 보장하는 `!!`키워드 (하지만 지양하셔야되고)
?. (safe-calls)는 null이 아닐때만 실행하게 할 수 있어요. //다만, null일 경우 null이라고 그대로 출력이 됩니다.
그래서 ?: , 앨비스 연산자를 통해서 null이 아닐때와 null일때를 구분할 수 있고 null이라는 문자열 대신에 다른 문자열로 대체해서 출력도 할 수 있게 됩니다.
'Kotlin > 스파르타_코틀린 문법' 카테고리의 다른 글
Kotlin - 컬렉션/ list, set, map / listOf, setOf, mapOf / mutableListOf, ArrayList, mutableMapOf,mutableSetOf/contains/ union,intersect,subtract (0) | 2023.08.03 |
---|---|
Kotlin - 4-7강 배열 / array , arrayOf (4) | 2023.08.02 |
kotlin4-4 지연 초기화 (0) | 2023.08.02 |
kotlin4-3 예외처리의 필요성 (0) | 2023.08.02 |
kotlin4-2 예외처리의 활용 (0) | 2023.08.02 |