Flutter - Dart 기초(1)
Flutter 문법 정리
1. 자료형 dynamic과 var의 차이 : dynamic은 선언과 동시에 fixed되지 않기에 String값으로 선언하더라도 이후 int, double, boolean 등의 다른 자료형으로 값을 넣을 수 있지만 var은 어떤 자료형이든 일단 넣고 나면 선언과 동시에 fixed 되기에 이후 동일 자료형의 다른 값은 넣을 수 있지만 다른 자료형 값은 넣지 못한다.
2. 변수.runtimeType : 변수 자료형 리턴
3. nullable과 non-nullable : null이 들어갈 수 있는 자료형과 들어가지 못하는 자료형이 구별된다는 것, 만약 String? name = '뉴진스'; 하면 name은 nullable, 만약 print(name!);? --> name이 절대 null이 아니다라는 것을 알려주는 의미 - 즉 널이 들어갈 수 있는 변수에다가 !를 붙이면 해당 값은 현재 널이 아니다라고 알리는
4. final, const : final String name = '뉴진스'; 처럼 변수 자료형 앞에 final 선언 시 해당 값은 더이상 수정불가한 상수가 되는 것, 그렇기에 name='블랙핑크'; 로 수정하려해도 오류 리턴, 바꾸지 않음 / 자료형 앞 const를 붙여주어도 도 동일함 / var역할 해주기에 final 이후 데이터타입 생략하여 final name='뉴진스'; 해도 된다 const도 마찬가지
5. final과 const의 차이점? :
DateTime now = DateTime.now(); 로 현재시간을 불러오는 변수 now를 만들고 print하게 되면 현재 시간이 나타남. const의 경우 빌드타임의 값을 알고있어야 하는 반면, final은 빌드타임의 값을 알지 않아도 됨 , 즉 컴퓨터는 프로그래밍 언어가 빌드되는 시간을 가지는데(런타임) 컴퓨터가 이해할 수 있는 이진수로 변환되는 과정에서의 const는 실행되는 코드의 값을 알고있어야한다는 것, 하지만 위와같은 DateTime.now()함수는 빌드과정에서 불러오므로 const DateTime now = DateTime.now();는 불가, final DateTime now = DateTime.now();은 가능
6. ??= : nullable한 변수인 double을 선언해보자 - double? number = 4.0;
해당 number값은 final이나 const값이 아니기에 이후 null이든 다른 double값으로든 수정가능하다. number ??= 3.0;은 만약 number변수의 값이 null이라면 3.0으로 변경한다는 것으로, number가 non-null이라면 오류를 리턴한다.
7. 변수 타입 비교 : print(number1 is int); - number1이 int면 true리턴, 아니면 false리턴 / 반대는 print(number1 is! int); - number1이 int가 아니면 true리턴, 맞다면 false리턴
8. List 선언 : List<자료형> 리스트명 = [ 리스트 값 ]; 리스트 내 원자값들은 리스트의 자료형과 동일해야한다. 만약 List<String> newjeans = ['해린', '민지', '다니엘', '혜인', '하니']; 처럼 모두가 String값이 와야한다, list는 파이썬과 동일하게 리스트명.length와 같이 길이도 리턴가능 .add로 값 추가 가능 .remove로 값 제거가능 .indexOf로 해당 값이 몇번째 인덱스인지 리턴 가능
9. Map : 파이썬의 dictionary와 동일하게 키와 밸류값으로 이루어진 자료형. Map<Key 자료형 : Value자료형> Map이름 = {key:value, key:value}; 와 같은 형식으로 선언.
즉 Map<String : String> HarryPorter = {'HarryPorter' : '해리포터', 'Herrmione' : '헤르미온느'}; 와 같이 선언해줄 수 있고 값을 추가하려면 HarryPorter.addAll({Key:Value});로 넣어주면 된다, 원하는 키의 값을 가져오려면 HarryPorter['HarryPorter']을 불러제껴주면 된다 - 그러면 value 값인 '해리포터'가 리턴, 혹은 저렇게 불러서 = 대입연산자로 값을 바꿔주거나(HarryPorter['Herrmione'] = '엠마왓싱') 추가해줄 수도 있다(HarryPorter['Hulk'] = '헐크'). 삭제는 HarryPorter.remove(키값); 해주면 키와 밸류값 쌍이 삭제, HarryPorter.keys는 키값들만 리턴, .values는 밸류값들만 리턴
10. Set : 맵과 유사하지만 키와 밸류짝이 아니고 리스트와 유사, 리스트는 중복값이 가능하지만 Set은 중복값을 자동으로 처리해줌. 선언은 Set<자료형> Set이름 = {}; 예로 final Set<String> names = {'hey', 'hey', ' dude', 'police'}; 해서 print(names)해보면 hey 중복을 제거한 {hey, dude, police} 만 리턴. 값 추가는 .add(값), .remove(제거값), 값이 있는지 확인하는 것은 names.contains('hey'); - true리턴
11. if, switch문, for, while, do while문은 c와 동일
12. for loop에서 각 개별값들을 roTlq쿨하게 가져오기 :
for(int i = 0; i < n.length; i++){
sum += n[i];
}
print(sum);
말고, 개별 값들을 바로 출력
for(int number in numbers){
sum += number;
}
과 같이 in loop을 해줄 수도 있다는 것(파이썬과 유사)
13. enum :
enum Status { approved, pending, rejected }
void main() {
Status status = Status.pending;
if (status == Status.pending) {
} else if (status == Status.approved) {
} else if (status == Status.rejected) {}
}
왜 enum을 쓰냐? 1. 정확히 세 개의 status만을 가진다는 것을 나 혹은 다른 개발자에게 알려주는 역할이기도 하고, 2. 오타가 날 시 바로 else로 넘어가지 않고 오타의 에러를 통해서 status 강제할 수 있기에
14. 함수 : c와 동일
void main() {
print(addNumbers(1, 3));
}
int addNumbers(int a, int b){
int sum = 0;
sum = a + b;
return sum;
}
* 위 addNumbers에 들어가는 parameter은 1. positional parameter - 순서가 중요한 파라미터(=argument, 매개변수)
2. optional parameter? x값은 필요, y, z는 필요없어도 되는 함수
void main() {
print(addNumbers(1, 3));
}
int addNumbers(int a, [int b = 20, int c = 30]){
int sum = 0;
sum = a + b + c;
return sum;
}
optional parameter은 저렇게 대괄호로 인자를 감싸주면 해당 부분은 옵셔널이 된다(호출 시 넣어도, 안넣어도). 다만 초기 값을 넣어주어야 함(기본값), 값을 넣으면 기본값은 무시되고 넘긴 인자가 들어감
3. named parameter?이름이 있는 파라미터(순서가 중요하지 않음)
void main() {
print(addNumbers(y: 20, x: 10, z: 30));
}
int addNumbers({required int x, required int y, required int z}){
int sum = 0;
sum = x + y + z;
return sum;
}
함수 정의부분 헤더에서 중괄호로 감싼 부분에 required 자료형 변수명 순서로 named parameter을 정해주면, 호출 시 해당 파라미터가 어떤 값을 가리키는지 콜론을 통해 매핑시켜서 함수 호출가능하다(순서 바뀌어도 가능하다)
named parameter에서 required를 빼면 optional parameter 가능하다(기본값 넣어주면)
void main() {
print(addNumbers(x: 10, y: 20));
}
int addNumbers({required int x, required int y, int z = 40}){
int sum = 0;
sum = x + y + z;
return sum;
}
15. Arrow 함수 :
int addNumbers({required int x, required int y, int z = 40}) => x + y + z;
함수가 수행하는 중간 과정을 짧게 나타내는 함수, 해당 명령을 수행한 값이 바로 리턴된다.
16. typedef : 함수와 유사, 하지만 body가 없다
typedef Operation = int Function(int x, int y, int z);
double 자료형을 리턴하는 int x, y, z를 가지는 function함수와 동일한 형식(signature)의 함수를 생성가능
void main(){
Operation operation = add;
int result = operation(10, 20, 30);
print(result);
operation = subtract;
int result2 = operation(30, 20, 10);
print(result2);
}
typedef Operation = int Function(int x, int y, int z);
int add(int x, int y, int z) => x + y + z;
int subtract(int x, int y, int z) => x - y - z;
typedef Operation으로 지정한 함수의 signature와 동일한 함수 add와 subtract를 각각 operation에 할당하여 사용할 수 있다.
현실적으로 이렇게 사용하진 않고 아래와 같이 사용
void main(){
int result1 = calculate(30, 20, 10, add);
print(result1);
}
typedef Operation = int Function(int x, int y, int z);
int add(int x, int y, int z) => x + y + z;
int subtract(int x, int y, int z) => x - y - z;
int calculate(int x, int y, int z, Operation operation){
return operation(x, y, z);
}
signature와 같은 함수를 함께 인자로 보내주면서 함수를 사용하는 것이다