달력

112024  이전 다음

  • 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

Any타입 변수는 자료형이 특별히 정해 지지 않은 경우에 사용한다. 

코틀린 에서 Any은 모든 클래스(변수) 의 엄마 이다.

Int, 나 String 나 사용자가 만든 클래스 까지 모두 Any형의 자식인 셈.

 

 

 

 

모든 클래스(변수)의 엄마니까 언제든 모든 자료형으로 자동변환이 가능하다.

이런것을 묵시적변환  이라고 하는데 다음 예제를 보자

println("===============묵시적변환 Any 테스트 START================")
var anyTest: Any = 1
if (anyTest is Int) {
typeStr = "anyTest Int:"
}else if(anyTest !is Int){
typeStr = "anyTest 머임:"
}
println("$typeStr $anyTest") // 변환전 타입을 확인

anyTest = 45L // Long 타입을 대입하여 자동변환을 확인해봄
if (anyTest is Long) {
typeStr = "anyTest Long:"
}else if(anyTest is Int){
typeStr = "anyTest 아직 Int임:"
}
println("$typeStr $anyTest") // Long 타입으로 자동
println("변수 anyTest의 변환된 타입은: ${anyTest.javaClass}") // anyTest의 자바 기본형을 출력하면 long
println("===============묵시적변환 Any 테스트 E N D================")

결과는 

===============묵시적변환 Any 테스트 START================
anyTest Int: 1
anyTest Long: 45
변수 anyTest의 변환된 타입은: long
===============묵시적변환 Any 테스트 E N D================

Any 타입의 형변환 되는 과정을 봤다. 

근데 참고로 실무에서는 마구잡이로 쓰진 않는다. 


코틀린에 어떤 Error 가 있는지 궁금하면?? 클릭 -> [코틀린] 오류코드 정리 :: 리뎁

자료형 과 변수가 궁금 하다면 ? 클릭 -> [코틀린] 자료형과 변수 & 엘비스 연산자 :: 리뎁

이중등호 삼중등호가 궁금하면? 클릭 -> [코틀린] 자료형 비교/변환 - 이중등호-삼중등호 :: 리뎁

코틀린 스마트캐스트 ? 클릭 -> [코틀린] 스마트캐스트 :: 리뎁

Posted by redev
|

자료형 검사하기

자료형 검사를 해보자 

val a4: Int = 128
val b4: Int? = 128

println("===자료형 검사===")
if (a4 is Int) {
println("a4 는 Int 형입니다.")
}

결과는 

===자료형 검사===
a4 는 Int 형입니다.

그럼 위에 스마트캐스트 테스트한 2-4.1 에서 작성 코드로 자료형 잘 변환 되었는지 확인 해 보자 

println("===============Number형 smartcast 테스트 START================")
var NumbTest: Number = 21.2
var typeStr = ""

if (NumbTest is Number) {
typeStr = "Number:"
}else{
typeStr = "뭘까요?:"
}
println("$typeStr $NumbTest") // Float 형 smartcast 테스트

NumbTest = 21
if (NumbTest is Int) {
typeStr = "Int:"
}else if(NumbTest is Number){
typeStr = "Number:"
}
println("$typeStr $NumbTest") // Int 형 smartcast 테스트

NumbTest = 21.3
if (NumbTest is Float) {

typeStr = "Float 상수값:"
}else if(NumbTest is Number){

typeStr = "Number 상수값:"
}

println("$typeStr $NumbTest") // Float 형 smartcast 테스트

NumbTest = 210L
if (NumbTest is Long) {
typeStr = "Long:"
}else if(NumbTest is Number){
typeStr = "Number:"
}
println("$typeStr $NumbTest") // Long 형 smartcast 테스트

NumbTest += 21.1f
if (NumbTest is Float) {
typeStr = "Float:"
}else if(NumbTest is Number){
typeStr = "Number:"
}
println("$typeStr $NumbTest") // Float 형 smartcast 테스트
println("===============Number형 smartcast 테스트 E N D================")

결과는 

===============Number형 smartcast 테스트 START================
Number: 21.2
Int: 21
Number 상수값: 21.3
Long: 210
Float: 231.1
===============Number형 smartcast 테스트 E N D================

잘 보면 알겠지만 최초 Number 타입은 Number로 인식한다....(당연한건가.ㅋ) 

이후 형변환이 되면서 각 자료형에 맞게 출력되는데 

중간에 추가된 붉은색 부분은 여전히 Number로 인식한다. 

Float로 인식시키려면 "21.3F" 라고 해야함.

 

 


코틀린에 어떤 Error 가 있는지 궁금하면?? 클릭 -> [코틀린] 오류코드 정리 :: 리뎁

자료형 과 변수가 궁금 하다면 ? 클릭 -> [코틀린] 자료형과 변수 & 엘비스 연산자 :: 리뎁

이중등호 삼중등호가 궁금하면? 클릭 -> [코틀린] 자료형 비교/변환 - 이중등호-삼중등호 :: 리뎁

Posted by redev
|

스마트캐스트

어떤 값이 정수와 실수 모두를 사용한다면? 매번 자료형을 변환해도 되지만 

코틀린 컴파일러가 자동으로 형 변환을 하는 스마트캐스트(Smartcast)를 사용하면 

더욱 편리할 수 있다.

대표적인 자료형은 Number 이다. 

아래를 보자 

println("===============Number형 smartcast 테스트 START================")
var NumbTest: Number = 21.2
println("$NumbTest") // Float 형 smartcast 테스트

NumbTest = 21
println("$NumbTest") // Int 형 smartcast 테스트

NumbTest = 210L
println("$NumbTest") // Long 형 smartcast 테스트

NumbTest += 21.1f
println("$NumbTest") // Float 형 smartcast 테스트
println("===============Number형 smartcast 테스트 E N D================")

결과는 

===============Number형 smartcast 테스트 START================
21.2
21
210
231.1
===============Number형 smartcast 테스트 E N D================

잘 처리 됨을 알수 있다. 

Number 의 자세한 내용은 추후 다뤄 보기로 한다.

 


코틀린에 어떤 Error 가 있는지 궁금하면?? 클릭 -> [코틀린] 오류코드 정리 :: 리뎁

자료형 과 변수가 궁금 하다면 ? 클릭 -> [코틀린] 자료형과 변수 & 엘비스 연산자 :: 리뎁

코틀린의 이중등호 삼중등호가 궁금하면? 클릭 -> [코틀린] 자료형 비교/변환 - 이중등호-삼중등호 :: 리뎁

 

Posted by redev
|

자료형 변환

코틀린(Kotlin) 만의 얘기는 아니겠지만 

코틀린에서는 자료형이 다르면 변환하여 대입해 주어야 한다. 

예를 들어 자바의 경우 

int a = 1;
double b = a; 

라고 하면 int 형인 a 를 double형인 b 에 대입하면 

자동으로 a 를 double 형으로 변환해 준다. 더 큰? 자료형으로 변환되는 것.

즉 b 의 값은 1.0 으로 자동 형 변환.

하지만 코틀린 에서는 Type mismatch 오류가 발생한다. 

아래의 예를 보자 

(그리고 자꾸 까먹는데.....코틀린에서 변수선언시 변수 타입의 첫글자는 문자로 하자 ㅠㅠ)

// 코틀린은 에러를 발생
val a1: Int = 1
val b1: Double = a1 // Int 형 변수인데 왜 Double에 넣음? 이건 에러!
val c1: Int = 1.0 // Int 형 변수인데 왜 소수점 넣음? 이건 에러!

그래서 뒤에 변환 메서드를 붙인다 

// 매우정상
val a1: Int = 1
val b1: Double = a1.toDouble()
val c1: Int = 1

 

이중등호 & 삼중등호

이중등호(==) 와 삼중등호(===) 는 값만 같은가 주소값 까지 같은가의 차이 이다.

아래를 보자 

// (1) 이중등호 , 삼중등호
val a3: Int = 128
val b3: Int = 128

println(a3 == b3) // true
println(a3 === b3) // true

// (2) 이중등호 , 삼중등호
println("삼중등호 널값 체크")
val a4: Int = 128
val b4: Int? = 128

println(a4 == b4) // true

println(a4 === b4) // false

"// (1)" 의 경우 이중부호, 삼중부호 모두 true 값이 나온다. 

"// (2)" 의 경우 이중부호 true, 삼중부호 false 값이 나온다. 

이유는 (1)의 경우 기본형으로 변환되어 스택에 128을 저장하게 된다. 

하지만 (2)의 경우 Null 값을 허용하는 참조형이므로 참조 주소가 저장되어 있기때문...

그런데 한가지 주의 할 점은 

만약 수치가 -128 ~127 사이에 있다면 모두 true가 나온다 

아래와 같이 ... 
val a4: Int = 123
val b4: Int? = 123

println(a4 == b4) // true
println(a4 === b4) // true 

이는 -128 ~ 127 까지의 값은 캐시에 값을 저장하고 변수는 캐시의 주소값을 가리키기 때문에 그렇다.

 

 


코틀린에 어떤 Error 가 있는지 궁금하면?? 클릭 -> [코틀린] 오류코드 정리 :: 리뎁

자료형 과 변수가 궁금 하다면 ? 아래를 클릭 -> [코틀린] 자료형과 변수 & 엘비스 연산자 :: 리뎁

 

 

Posted by redev
|

Error:(9, 5) Kotlin: Nested and local type aliases are not supported

원인 : typealias 를 class 또는 object 또는 어떤 Code-Block 에 넣었을때 오류가 발생 

해결 : thpealias 선언을 class 밖에 (맨위에 import 하는 바로 아래에) 선언

 

Error:(25, 23) Kotlin: Null can not be a value of a non-null type String

원인 : 변수 타입을 지정후 기본값을 null 값으로 했을때 발생 

해결 : 변수 선언시 null 값을 지정하지 않는다. 필요시 ? 로 선언 

참고 : IntelliJ 를 사용한다면 빨간 밑줄이 그어짐.

 

Error:(72, 52) Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

의미 : String? 형은 SafeCall인 (?.) 또는 non-null 단정(강제) 기호인 (!!.) 만 허용한다. 

원인 : null 허용된 a변수에 null 값이 할당되었는데 a를 읽을때 (NullPointerException) 발생함.  

해결1 : 조건절로 Null Check 하여 Null 값을 읽는 일이 없도록 함.

해결2 : Safe Call 기호 ?로 처리함. 

해결3 : 단정기호 !!를 사용함. 

참고 : Safe Call -> null이 할당된 가능성이 있는 변수를 검사하여 안전하게 호출하도록 하는 기법

Safe Call Example : 

var nullTest: String?

nullTest = null

println("nullTest: $nullTest")

println("nullTest: $nullTest length: ${nullTest?.length}")

Result >null이 아니면 값을 읽고 null 이면 그냥 null을 찍음. nullTest: null length: null

 

Exception in thread "main" kotlin.KotlinNullPointerException 
at chap02.section2.VarTestKt.main(varTest.kt:73)
at chap02.section2.VarTestKt.main(varTest.kt)

의미 : main 메소드에서 NullPointerException 이 발생하였음. (varTest.kt 파일 , at 73 Line)

원인 : null 허용된 a변수에 null 값이 할당되었는데 a를 읽을때 (NullPointException) 발생함.  

해결1 : Null 값인 변수를 참조 하지 않게 함. or Null 처리 함.

 

Error:(103, 22) Kotlin: Type mismatch: inferred type is Int but Double was expected

원인 : 선언된 변수와 대입하는 값이 타입이 다름.

해결 : 변수 타입과 변수값을 맞추자.

 

Error:(104, 19) Kotlin: The floating-point literal does not conform to the expected type Int

의미 : Int 타입인데 float 타입으로 소수점이 들어 왔으니 난 인정 못하겠다 

원인 : Int 형 변수에 소수점 값이 있는 데이터가 들어가 있음. 

해결 : 변수 타입과 변수값을 맞추자.

참조 :  val c1: Int = 1.0 <- 오류 ,,,, val c1: Int = 1 <- 정상 

 

Error:(177, 28) Kotlin: Incompatible types: Float and String

의미 : 다음 두개의 타입을 인정 못하겠음. 

원인 :  String 상수(constant)값을 지정 하고 뒤에서 Float으로 검사,변환 및 사용하면 발생

해결 : 선언된 타입으로 잘 진행 

참조 : 

 

 

Posted by redev
|

변수 선언

Kotlin에서 변수를 선언할땐 

val  var을 구분해야 한다.

val 은 상수값을 대입하기 위해 사용한다.  (최초 지정한 변수값에서 변경할 수 없음)

var 은 변수값을 대입하기 위해 사용한다. 

이때 상수 val 은 자료형(타입)을 선언하지 않으면 Kotlin은 변수에 할당된 값으로 자료형을 자동으로 지정한다.

예를들어 

val userNm = "Gildong" 이라고 하면 userNm은 String 타입으로 자동인식.

물론 val userNm: String ="Gildong" 으로 해도 된다.

var 역시 마찬가지.

 

자료형 

프로그래밍에서 자료형을 "기본형 자료형" 과 "참조형 자료형" 으로 구분한다. 

코틀린에서는 "참조형 자료형"만 사용한다. 

기본형 과 참조형이 무엇인지 살짝 짚어보면 

예를들어 자바의 경우 

기본형 자료형 : int, long, double 등을 말하고 

참조형 자료형 : String, Date, 사용자가 정의한 객체 등을 말한다. 

아무래도 참조형 보다 기본형이 성능면에서 좀더 우월하다. 

코틀린은 컴파일시 참조형을 기본형으로 대체 되니 성능 최적화를 위한 자료형은 딱히 신경쓰지 않아도 된다.

음... 

혹시 이부분은 참고하는게 좋을 것 같다. 

typealias를 쓰는 경우 아래와 같은 메세지를 만날수 있는데 

Kotlin: Nested and local type aliases are not supported

typealias 선언을 클래스나 오브젝트 안쪽에 넣은 경우 발생한다. 

 

자료형의 검사와 변환

코틀린은 기본적으로 null 을 허용하지 않는다. 

null 을 허용하려면 ?를 사용해야 한다. 

예를 들어 자바는 

String str = null

이런식으로 null 이 허용 되지만 

코틀린은 

var str: String = null 이라고 하거나 

var nullTest: String = "test"

nullTest = null 

라고 하면

Error:(25, 23) Kotlin: Null can not be a value of a non-null type String 

와 같은 오류가 발생한다.

하지만 ?를 사용하여 (여기서 ? 를 Safe Call 이라고 함)

var nullTest: String? ="test"

nullTest = null 

라고 하면 오류가 발생하지 않는다. 또는 단정부호 (!!) 를 사용해도 오류가 발생하지 않는다. 

var nullTest: String?

nullTest = null

println("nullTest: $nullTest length: ${nullTest!!.length}") // 단정부호 !! 를 사용함.

단, 단정부호 !! 사용시 Compile 시에는 오류가 발생하지 않지만 

RunTime 시 아래와 같이 NullPointerException 이 발생할 수 있다.

Exception in thread "main" kotlin.KotlinNullPointerException 
at chap02.section2.VarTestKt.main(varTest.kt:73)
at chap02.section2.VarTestKt.main(varTest.kt)

※ 참고 ※

null 값과 "" 은 다른 값으로 인식함.

 

Elvis(엘비스) 연산자

코틀린(Kotlin) 에만 있는건 아니지만 여튼 코틀린 에는 엘비스(Elvis) 연산자가 있다. 

?:  <-- 요렇게 사용한다. 

문법 내용은 

aaaa ?: bbbb  엘비스 연산자 ?: 를 기준으로 변수가 null 인지를 검사하여 

null 이 아니면 aaaa를 null 이면 bbbb 를 실행하는 것.  아래와 같이 사용

var nullTest: String?

nullTest = null

println("nullTest: $nullTest length: ${nullTest?.length ?: -999 }") // Safe Call ? 와 엘비스 연산자 ?: 를 같이 사용함.

결국 아래 참고 조건절과 같은 내용인데 단순 조건절을 한줄로 표현 할 수 있으니 가독성 측면에서 

엘비스 연산자가 효율적이다.

참고 : if ( nullTest != null) nullTest.length else -999

 

 

 

 

Posted by redev
|

자바 또는 다른 언어로 개발해본 사람이면 모두 변수, 자료형, 연산자에 대해 알고 있다.

물론 나 역시 알고있다.

그래서 사실 2장은 그냥 Skip 해도 상관 없지만 

블로그의 목적상 작성하고 넘어간다.

우선 자료형을 공부하기 전에 모듈과 패키지의 개념을 짚고 넘어가자

Project , Module , Package, File 

코틀린의 프로젝트(Project)는 모듈(Module), 팩키지(Package), 파일(File) 로 구성되어 있다. 

당연히 모듈이 가장 큰 단위 -> 파일이 가장 작은 단위라고 보면 된다.

 

프로젝트(Project)

프로젝트는 최상위 개념이라고 보면 되겠다. 

예를들어 비용등록 프로그램(A), 고객관리 프로그램(B), 수정요청관리 프로그램(C)을 각각 만든다고 하면 

세개의 프로젝트가 될것이다 (물론 저렇게 할 일은 없다....)

 

모듈(Module) 

모듈은 각각의 프로젝트에 있는 기능(대분류) 단위이다. 

실제 프로젝트시에 보면 모듈을 대분류단위 또는 업무구분 단위로 분리하게 될것이다. 

(구매/영업/생산 ... + 공통영역.. 등등)

예를들어 (A) 프로그램에는 비용등록(A1), 비용코드관리(A2), 거래처관리(A3) .. 등이 모듈이 될것이다. 

 

패키지(Package) 

패키지는 상황에 따라 좀 다르다. 

기능적으로 분류할 수도있고 작업단위로 분류할 수도 있다. 

프로젝트의 성격과 인원 자사의 Framework 등에 따라 조금씩 다르게 정의할 수 있겠다.

또한 배포의 문제도 감안해야 할 것이다. 

단순 SI인지 솔루션 기반으로 진행할 것인지 등도 감안해야 하겠다. 

어쨋든 지금은 모듈의 하위단에 있다는 정도로 이해하자.

한가지 기억할 점은 

코틀린 파일의 맨 위에는 어떤 패키지에 포함 되었는지 명시해야 한다. 

패키지를 명시하지 않으면 default 패키지에 포함된다.

(파일이 위치한 폴더와 관계없다)

 

파일(File) 

음.....그렇다. 이건 파일이다.

코틀린 파일의 확장자는 .kt 인데 파일안에 하나의 클래스만 있는경우 프로젝트창에서 .kt 는 생략된다. 

하나의 파일안에 여러개의 클래스가 있는경우 파일은 단순히 클래스를 묶는 역할만을 하고

프로젝트 창에서 .kt 확장자를 볼수 있다. (여러개의 클래스인 경우 상단에 있는 패키지를 인식한다.)

참고로 코틀린은 자바처럼 파일명과 클래스명이 동일 해야하거나

public 클래스를 하나만 써야 하는 규칙은 없다.

 

팩키지 생성 

IntelliJ 실행 > New 프로젝트(Project) 생성 > 프로젝트 창에서 src 폴더 우클릭 > New > Package 클릭 > 이름짓기 

New 프로젝트 생성을 모른다면 아래 클릭

https://redev.tistory.com/3?category=812832

그러면 src 폴더 밑에 본인이 지어준 팩키지 이름이 보일 것이다.  (나는 com.example.edu 로 했다.)

탐색기를 열어보면 . (점)을 기준으로 폴더가 생긴것을 확인할 수 있다.

 

팩키지 alias 

예를들어 com.example.edu 의 clss1 을 import 하여 사용한다고 가정하면 

import com.example.edu.clss1 라고

현재 코딩중인 파일의 상단에 이렇게 import할 것이다. 

근데 만약 clss1 이 현재 패키지에 이미 존재한다면 충돌이 날것이다. 

그렇기에 edu.clss1 에 alias를 줄수 있다. 

import com.example.edu.clss1  as eduClass1 과 같은 식으로..

alias 개념은 다 알것이니 설명은 생략하고 

실전에서는 저렇게 쓰는일이 많지는 않을것 같다 

뭐 성능적으로 import com.example.* 와 같은식은 퍼포먼스 측면에서 사용하지 말라고 하긴 하는데

import com.* 수준이 아니라면 import com.example.* 는 어느정도 허용이 될것이다. 

그러면 alias를 쓰지 못할테니....그리고 파일명칭을 충돌시키는 Naming Rule 자체를 권장하지 않는다.

하지만 상황봐서 유용할 수 있으니 알아 두어야겠다.

 

 

 

 

Posted by redev
|

사실 순서로 보자면 "코틀린 이란?"  또는 "Why Kotlin?" 뭐 이런게 어울릴거 같지만 

여튼 시작해보자

 

개발환경 Setup 

Kotlin 역시 JDK를 사용한다. 

Oracle 에서 유료화 했으므로 OpenJDK인 Zulu로 JDK를 대신한다. 

아래 주소에서 JDK SE8 다운로드 후 설치 한다. (이미 JDK가 있다면 ??? 그냥 그거 쓰면 된다)

https://www.azul.com/downloads/zulu 

 

Azul Systems Better Java Performance Superior Java Support

Better Java Performance Superior Java Support JDK 8 support plans JDK 11 Java JVM Zing Zulu Enterprise Zulu Embedded OpenJDK Solve GC OpenJFX

www.azul.com

환경변수 설정 

JDK를 설치 했으니 환경변수에 JAVA HOME을 잡아준다.  (역시 이미 설정되어 있다면? Skip ~)

( 음...누군가 이글을 볼지 모르겠는데.... JAVA HOME 설정은 Googling 하시길...

"JAVA HOME 환경변수" 이렇게 검색해 보시면 됩니다. )

 

Java version 확인

정상적으로 설치 되었다면 cmd 창에서 

java -version 이라고 쓰고 엔터를 치면 

openjdk version "1.8.0_xxx" 뭐 이런식으로 나오면 환경 변수까지는 끝. 

 

IDE 설치 

IDE 란 Integrated Development Environment 의 약자이다 

직역하면 "통합된 개발 환경" 인데....쉽게 말해 개발 Tool을 의미한다. 

예를들면 Netbeans, Eclipse, IntelliJ IDEA 같은것들...

여기서는 IntelliJ IDEA를 사용한다. (보통은 IntelliJ라고 부른다 "인텔리제이")

(근데....갑자기 궁금해 지는게... intelli 는 intelligent 의 약자일거같고 J 는 Java 겠지...???)

그러니 아래 링크에서 설치 Ultimate는 유료이니...Community에디션을 다운 받는다

https://www.jetbrains.com/idea/download/ 

 

JetBrains: Developer Tools for Professionals and Teams

JetBrains is a cutting-edge software vendor specializing in the creation of intelligent development tools, including IntelliJ IDEA – the leading Java IDE, and the Kotlin programming language.

www.jetbrains.com

뭐 테마 설정하고 이런게 있는데 그런건 그냥 "기본값"으로... 하는게 정신건강에 좋다는걸

17년의 감각이 알려주고 있다...ㅋ

 

또 만났군 HelloWorld ......

이제 프로젝트를 만들어야 한다. 

프로젝트는 "작업하는 프로그램(제품) 단위"라고 이해하면 된다.

IntelliJ 를 실행하면 Welcome 화면이 뜨면 아래 순서로 진행하면 된다.

(1) + Create New Project 클릭 

(2) 왼쪽 리스트에서 Kotlin 선택

(3) 우측 리스트에서 Kotlin/JVM 선택 후 Next

(4) 프로젝트 명 입력창이 뜨면 HelloKotlin 으로 입력 후 [OK] 버튼 클릭

(한글은 사용하지 않는게 역시 건강에 좋다)

참고로 글꼴은 D2Coding 으로 설정해 준다. (File > Settings에서 설정)

(5) 편집기 화면에 main 입력후 [Tab] 버튼을 클릭하면 main() 함수가 만들어진다

fun main(){

   println("Hello redev") 

}

 

(6) Run 해본다 ( 상단 메뉴 > Run > Run 해도됨.)

"Hello redev" 라는 Text가 IntelliJ 콘솔창에 뜨면 성공

 

그럼 개발환경 셋팅은 일단 끝.

새벽 1시가 넘었다... .졸립네....

 

 

Posted by redev
|