플러터Flutter 데이터 타입

휘Bin·2023년 6월 19일
0
post-thumbnail

다트 언어에서 모든 변수는 객체이다. int, double, 다 객체이다.
따라서 int 타입 변수는 객체이므로 null을 대입할 수 있게 되고, int 클래스에 선언된 변수와 함수를 이용할 수 있게 된다.

int? no = 10;

main(){
	bool? data = no?.isEven;
    no = null;
    Object? obj = no;
}

여기서 int 타입의 no 변수를 선언했다. int는 dart:core 라이브러리에서 제공하는 클래스이므로 no 변수는 int 클래스의 객체인 것이다.
그러므로 int 클래스에 선언된 isEven 속성을 사용할 수 있게 되고, 다트의 최상위 클래스인 Object에 대입할 수 있게 되는 것이다.

다트의 타입 클래스

다트에서는 dart:core, dart:typed_data 라이브러리에서 클래스로 타입을 제공받는다. 숫자를 저장하는 num 클래스도 제공하는데, int와 double 클래스는 num을 상속받게 되는 것이다.

※ 다트에서 제공하는 데이터 타입 클래스는 따로 한번 알아보길!

문자열 표현하기

다트에서 문자열 데이터를 다룰 때는 String 클래스를 사용하고, 코드에서 문자열은 작은 따옴표('')나 큰따옴표(""), 또는 삼중 따옴표('''''', """""") 등으로 감싼다.
여기서 삼중 따옴표를 이용하게 되면 문자열에서 엔터나 탭 등이 그대로 반영되게 된다.

두 문자열이 같은지 비교할 때는 == 를 사용한다.

문자열에 동적인 결과를 포함하는 것을 '문자열 템플릿'이라고 하는데, 이때는 $ 기호를 이용한다. 어떤 변수를 문자열에 포함하려면 $변수명 형태로 작성하고, 실행문의 결과를 포함할 때는 ${} 형태로 작성한다.

형 변환하기

다트에서 int, double 타입의 변수가 모두 객체이기 때문에 '형 변환'도 자동으로 이뤄지지 않는다.
int를 double 타입으로, 혹은 반대로 변환하려면 함수를 이용해야 한다.
Ex)

main(){
	int i1 = 10;
    double d1 = 10.0;
    
    double d2 = i1.toDouble();
    int i2 = d1.toInt();
}

int와 Sring 형 변환도 함수를 이용하게 된다.
Ex)

main(){
	int i1 = 10;
    String s1 = '10';
    
    String s2 = i1.toString();
    int i2 = int.parse(s1);
}

상수 변수 - const, final

상수 변수는 초깃값을 대입한 후에는 바꿀 수 없다. 그런데 특이하게 다트에서는 상수가 되는 시점에 따라 컴파일 타임런 타임 상수 변수로 구분된다.

컴파일 타임 상수 변수 - const

컴파일 타임 상수 변수는 const 예약어로 선언한다.
const 변수는 톱 레벨이나 함수 내에 지역 변수로 선언할 수 있지만, 클래스에 선언할 때는 static 변수로만 선언할 수 있다.
const 변수는 컴파일 단계에서 상수가 되어 변수를 선언할 때 초깃값을 대입해야 하고, 이후에는 역시 그 값을 바꿀 수 없다.

런 타임 상수 변수 - fianl

final 예약어로 선언하는 런 타임 상수 변수는 톱 레벨 뿐 아니라, 클래스나 함수 내부에도 선언할 수 있다. final로 선언한 변수도 상수이므로 const와 마찬가지로 값을 바꿀 수는 없지만, 초깃값을 대입하는 시점이 반드시 선언문이 아닐 수도 있다는 것이 다르다.

즉, final로 선언한 변수도 상수이므로 초깃값을 대입한 후에는 값을 바꿀 순 엇지만, 먼저 선언하고 객체를 생성할 때나 함수에서 값을 참조하기전에 초깃값을 대입할 수 있다는 것이다. 즉, 앱이 실행될 때 값이 결정되어서 런 타임 상수 변수라 한다.

상수 변수와 문자열 템플릿

문자열 템플릿에 상수 변수를 사용할 때는 주의할 점이 있다! const 예약어로 선언한 String 타입 상수 변수에 문자열 템플릿으로 값을 대입할 때는 템플릿 내부에도 컴파일 타임 상수를 사용해야 한다.

Ex)

main(){
	String s1 = 'hi';
    const String s2 = 'hello';
    final String s3 = 'hihello';
    
    String s4 = '$s1,$s2';
    const String s5 = '$s2';
    const String s6 = '$s1, $s2, $s3'; => 오류
    final String s7 = '$s1, $s2. $s3';
}

var 타입과 dynamic 타입

다트에서는 변수를 선언할 때, int, double, bool 등의 타입 대신에 var, dynamic 이라는 타입을 사용할 수도 있다. var, dynamic은 타입을 유추하거나 모든 타입의 데이터를 대입할 수 있는 변수를 선언할 때 사용한다.

타입 유추 - var

var로 변수를 선언할 때는 타입을 생략한다. 그리고 이 변수의 타입은 대입하는 값에 따라 결정된다. 즉, 컴파일러가 해당 변수에 대입하는 값을 해석해 타입을 추측한다.

main(){
	var v1 = 10;
    v1 = 20;
    v2 = 'hi' => 오류
}

var로 선언한 변수는 초깃값을 대입하는 순간 그 값의 타입으로 결정되지만, 선언과 동시에 값을 대입하지 않으면 타입을 알 수 없기 때문에 dynamic 타입으로 선언된다.

main(){
	var v1;
    v1 = 10;
    v1 = 'hi';
    v1 = true;
}

모든 타입 지원 - dynamic

변수에 타입이 아닌 dynamic을 사용하면 모든 타입의 데이터를 대입할 수 있다. 바로 위와 같다.

컬렉션 타입 - List, Set, Map

'컬렉션' 타입이란 한 변수에 여러 데이터를 저장하는 방법으로, 배열(Array), 리스트(List), 집합(Set), 맵(Map) 등이 있다.
'배열'과 '리스트'는 여러 데이터를 저장하고 저장된 순서를 나타내는 인덱스값으로 이용하는 공통점이 있다. 즉, 다트에서는 둘을 구분하지 않으므로 배열이 리스트이고, 리스트가 곧 배열이라고 생각하면 된다.

리스트 타입

List는 데이터를 여러 개 저장하고 인덱스값으로 데이터를 이용하는 컬렉션 타입의 클래스이다. 리스트를 선언하면서 초기화할 때는 대괄호([])를 사용한다.
변수를 List 타입으로 선언하면서 대입할 데이터의 타입을 지정하지 않으면 dynamic 타입 리스트가 된다.

Ex)

main(){
	List list1 = [3,'hi', true];
}

특정한 타입의 데이터만 저장하는 리스트를 선언할 때는 해당 데이터 타입을 '제네릭'으로 명시해주면 된다.

Ex)

main(){
	List<int> list = [1,2,3];
}

리스트를 선언할 때 초기화한 데이터에서 더 추가하거나 제거하려면 add(), removeAt() 함수를 이용한다.

리스트를 선언할 때, 데이터를 몇 개 저장할지 크기를 지정할 수 있다. 이때는 filled(), generate() 함수를 사용한다.
filled(), generate()는 List 클래스에 선언된 생성자이다. 그리고 생성자란 객체를 만들 때 자동으로 실행되는 함수이다. 즉, 생성자를 호출하면 객체가 생성된다고 쉽게 생각하면 된다.
만약, 처음에 지정한 크기보다 많은 데이터를 저장할 수 있게 허용하려면 filled() 생성자에 growable 매개변수를 true로 지정해주면 된다.

Ex)

var list = List<int>.filled(3,0,growable: true);

리스트를 초기화할 때, 특정한 로직으로 구성된 데이터를 지정할 수도 있다. 이때는 초깃값을 지정하는 두 번재 매개변수를 함수로 지정하면 된다. generate() 생성자가 이런 기능을 제공한다.

집합 타입

Set은 List와 마찬가지로 여러 데이터를 저장하는 컬렉션 타입의 클래스이고 인덱스값으로 데이터에 접근한다. 리스트와의 차이는 '중복 데이터를 허용하지 않는다'. 집합 타입 변수를 선언하면서 초기화할 때는 중괄호({})를 사용한다.

맵 타입

Map은 여러 건의 데이터를 키와 값 형태로 저장하는 타입이다. 맵에 저장되는 데이터는 항상 키를 가져야 하고, 저장된 데이터에 접근할 때는 인덱스가 아닌 키를 이용한다.

Ex)

Map<int, int> map1 = {'1':'10', '2':'20'};
profile
One-step, one-step, steadily growing developer

0개의 댓글