-
[Kotlin] 변수/자료형Kotlin/Types 2021. 7. 7. 19:04
main함수
fun main(){ } fun main(args:Array<String>){ }
변수 종류
var - 일반 변수 val - java의 final변수(한번 초기화하고 값을 변경 할 수 없음)
변수 선언 및 초기화
fun main(){ var a: Int //변수 선언 a= 3 //변수 초기화 } fun main(){ var a: Int= 3 //변수 선언과 동시에 초기화 } fun main(){ var a= 3 //Int타입 자동 추론(Inferred type) //var b; 변수 타입 지정없이 선언과 초기화 따로 불가능 //b=4; }
자료형
자료형을 설명하기 전에 자바와 코틀린의 다른 점
자바에서는 참조 변수에 명시적으로 null을 지정할 수 있었다. 또한 primitive타입에는 null을 넣을 수 없었다.
String str=null;
MyClass class=null;
int a= null (x)
코틀린에서는 일반적으로 선언된 var, val 변수는 non-null변수로 취급된다.
var str : String = "hello" (str은 non-null변수)
이러한 non-null변수는 null값을 가지면 안된다.
이러한 변수에 명시적으로 null로 초기화하면 컴파일 에러로 실행도 되지 않는다.
var str : String = null (x, 컴파일 에러)
프로그램 실행도중 null이 될 수 있는 변수들은 변수선언시 타입뒤에 ?를 붙여 nullable 변수로 만들어줘야 한다.
var str2 : String? = null (ok)
또한 다른 변수에 nullable변수를 대입할 경우 컴파일이 되지 않는다. 이는 프로그램 실행 전에 확실한 null체크를 강제하게 되어 실행도중 강제종료되는 것을 컴파일 시점에서 막는다.
var str1 : String? ="test"
var str2 : String = str1 //컴파일 에러
//여기서는 예제를 위해 단순히 null이 아니라 test값을 가지는 것을 알고 있지만
//str1은 nullable변수이므로 null값이 들어갔을 수도 있다고 취급된다.
//null체크 필요
nullable변수의 null관련 처리는 나중에 적겠다.
(추가)
https://hellose7.tistory.com/37
자바에서는 primitive int가 있고 Interger클래스도 있다. 코틀린은 모든 것이 객체이다.
코틀린은 자바의 int형 변수 선언시 코틀린 Int class로 선언한다.
자바의 Integer class에 대응되는 코틀린의 Int class를 사용하는 이유는정확히 설명불가. 알아서 찾아보기boxing, unboxing, Collection의 저장, Generics 과 관련되어 개발자들이 간편하게 쓰기 위해서var a : Int =3 //int a=3;
//내부적으로 stack에 jvm primitive타입인 int로 저장이 된다.
var b : Int? =null //Integer b=null;
//nullable한 Int는 null이 될 수 있으므로 Int?로 선언해야 하고
내부적으로 heap에 java의 Integer클래스의 인스턴스로 만들어진다.
자바에서는 primitive값은 null을 가질 수 없지만
코틀린에서 nullable한 Int, Long, Boolean변수를 선언하면 null이 들어갈 수도 있기 때문에
실제로 java의 Integer, Long, Boolean객체로 만들어지는 것이다.
https://zzdd1558.tistory.com/234
https://kotlinlang.org/docs/basic-types.html#numbers-representation-on-the-jvm
코틀린의 ==는 값 비교 , ===는 주소값 비교
jvm의 최적화에 따라 -128~127의 Int는 같은 주소값의 객체로 저장된다고 한다.
fun main() { val a: Int = 100 val boxedA: Int? = a val anotherBoxedA: Int? = a println(boxedA === anotherBoxedA) // true -128~127은 같은 주소값의 객체 참조 println(boxedA == anotherBoxedA) // true val b: Int = 10000 val boxedB: Int? = b val anotherBoxedB: Int? = b println(boxedB === anotherBoxedB) //false 이외의 범위라서 서로 다른 두 객체가 만들어짐 println(boxedB == anotherBoxedB) //true }
java에서는 ==가 주소값 비교였다. 값 비교는 오버라이딩된 equals메서드를 써야했다.
문자형 Char- 2byte
작은 따옴표로 감싼다.
Special characters start from an escaping backslash \. The following escape sequences are supported: \t, \b, \n, \r, \', \", \\ and \$.
var ch: Char = '문자'
var ch2: Char = '\u유니코드번호'
자바와는 다르게 정수형으로 취급되지 않는다.
//java public static void main(String[] args){ char ch=97; System.out.println(ch) // a } //kotlin fun main(){ //var ch: Char=97 컴파일 에러 }
코틀린에서 문자 숫자간 변환
fun main(args: Array<String>) { val charTest : Char = 'a'; //println('a' == 97) 에러 Operator '==' cannot be applied to 'Char' and 'Int' println('a'.toInt() == 97) } 출처: https://zzdd1558.tistory.com/234 [YundleYundle]
Char변수.toInt()로 변환하여 정수형과 비교해야함.
숫자에 해당하는 문자를 확인시 숫자.toChar()으로 문자형으로 변환 필요
논리형 Boolean - true, false
|| or
&& and
! not
「숫자형 = 정수형 + 실수형」
(공식문서에는 Number type = Integer타입 + floating point타입이라고 설명되어있다.)
(자바의 Wrapper class Integer, Number등과 헷갈리지 말도록 하자)
정수형
Byte- 1byte
Short- 2byte
Int- 4byte
Long- 8byte (접미사L. 소문자l안됨)
변수의 값 초기화시 10,20등을 나타내는 십진수 리터럴이 Int의 maximum값(자바의 int맥시멈 값)을 넘으면
inferred type추론으로 Long형으로 취급, maximum값 넘지 않으면 Int로 취급
//kotlin var one = 1 // Int형으로 추론 저장 var threeBillion = 3000000000 // Long형으로 추론 저장 var test : Int = 3000000000 //컴파일 에러. Int형 명시. Int형에 Int의 max값을 넘는 값 대입 불가 var test2 : Long = 300 //ok . //Inferred type추론아닌 Long형 명시하면 L안 붙여도 잘 저장되는듯 컴파일 에러는 없었다. //헷갈리니까 편하게 그냥 Long형 쓸꺼면 L붙이자.... 헷갈리네.... //java int one = 1; Long threeBillion = 3000000000L //java에서는 타입 생략도 불가능 하거니와 L을 붙이지 않으면 무조건 int로 취급되어 컴파일 에러
위의 것은 헷갈리니까 그냥 무조건 Long타입으로 설정할거면 무조건 L을 달자... 그게더 coding convension에 맞으니까.....
Byte,Short타입 변수 선언시에는 타입을 명시해야 할 것 같다. 안그러면 Int나 Long으로 취급되니
Unsigned integers- unsigned 지원한다.
실수형
Float- 4byte (F, f)
Double- 8byte
소수점 리터럴은 모두 Double취급됨
Float형 초기화시 소수점 리터럴에 F,f
소수점 6~7자리가 넘어가는 소수점 리터럴에 F 붙이면 6~7자리에서 rounded된 Float값으로 저장됨
val e = 2.7182818284 // Double val eFloat = 2.7182818284f // Float, actual value is 2.7182817
Floating-point numbers comparison
코틀린의 명시적 형변환 필요성
Kotlin의 숫자형(정수형+실수형)은 Java에서 적용되던 암묵적 widening conversion이 적용되지 않는다.
Note that unlike some other languages, there are no implicit widening conversions for numbers in Kotlin.
(변수에 다른 변수를 대입할 때 자동으로 넓은 형변환되는 것을 말한다. 넓은 자료형 변수에 좁은 자료형 리터럴을 넣는 것도 포함한다.)
java에서 적용된 widening conversion byte -> short-> int -> long -> float-> double char -> int int a=3; float b= a; (ok) char ch='a' int d= ch; (ok) kotlin은 안됨 1.변수 대입 에러 var a=3 //Int var b=4.3 //Double //b=a 에러 //java에서 int->double로 자동 형변환 되었던것 2.매개변수 대입 에러 fun main() { fun printDouble(d:Double){ print(d) } //printDouble(3) 에러 //자바에서 메서드 인자로 넘어갈때 3이 자동으로 double로 형변환되었던것 printDouble(3.0) } 3.return변수 에러 fun method():Double{ var a=3 //return a 에러 //return변수가 return될때 3이 자동으로 double로 형변환되어 return되었던것 }
그렇기 때문에 항상 명시적으로 형변환을 해줘야한다.
자료형 클래스마다 여러 자료형으로 변환하는 to자료형() 메서드가 존재하여 타입을 다른 타입으로 변환한다.
var a: Int =3
var b: Long = 5L
b= a.toLong() //Int class의 toLong()메서드
암묵적 산술 변환
arithmetical operations are overloaded for appropriate conversions, for example:
val l = 1L + 3 // Long + Int => Long
자바의 산술 변환 까먹어서 찾아봄
https://hs0955.tistory.com/174
코틀린에서는 모든 연산자가 메서드로 취급된다고 한다. (연산자 오버로딩)
https://kotlinlang.org/docs/operator-overloading.html
String
Strings are immutable
인덱싱이 가능함
fun main() { var str ="hello" println(str[0]) //결과 h. 자바의 str.charAt(0)과 같음 }
iterate가 가능함
fun main(){ var str="hello" for (item in str){ print(item) print(',') //h,e,l,l,o, } }
기존 java String +연산 가능
var str="hello" println(str+ "choi") //hello choi
String templates
큰따옴표 안에 $를 사용하여 기존 자바의 String덧셈 연산 출력을 편하게 사용할 수 있다.
property나 method의 결과를 포함시키려면 ${}를 사용하면 된다.
fun main(){ var a: Int=10 var b: Long=100L var c: Float=1.234F println("Int a is $a") // Int a is 10 // =println("Int a is"+ a) println("Long b is $b") // Long b is 100 println("Float c is $c") //Float c is 1.234 println("Float c to Int is ${c.toInt()}") //Float c to Int is 1 }
배열
Array class
get, set 메서드, size property, 다른 유용한 멤버들을 다루는 메서드들이 있다.
class Array<T> private constructor() { val size: Int operator fun get(index: Int): T operator fun set(index: Int, value: T): Unit operator fun iterator(): Iterator<T> // ... }
boxing overhead가 없는 primitive type array가 존재
ByteArray, ShortArray, IntArray, DoubleArray, CharArray, BooleanArray
Array, primitive array에 관하여 내부적으로 모르는 코틀린 문법이 많아 공부하고 써야할 것 같다.
참조형
클래스 타입이다.
'Kotlin > Types' 카테고리의 다른 글
[Kotlin] Array (0) 2021.12.16 [Kotlin] Nothing, Unit (0) 2021.08.16 [Kotlin] Type check and Type casts (0) 2021.08.13 [Kotlin] 코틀린 패키지 / .kt파일과 .java파일 (feat. top-level선언) (0) 2021.07.21 [Kotlin] val / const val (0) 2021.07.21