본문 바로가기
flutter 공부 기록소

Flutter 공부 기록 3

by riddleuscode 2023. 6. 15.

이어서 문법을 더 살펴보겠습니다.

List를 살펴볼건데, 자바에서 ArrayList만 사용하던 경험을 살려 dart에도 있나? 선언해보려니까

" Undefined class 'ArrayList'. "

여기 dart에서는 ArrayList는 없거나 대체 가능한 다른 타입이 있나봅니다.

선언은

List<int> list=[1,2];

요런 식으로 선언하고, 인덱스는 배열처럼 다룰 수 있습니다.

아, 의외로 List지만 길이는 size를 사용하지 않고 배열처럼 length로 알 수 있답니다. 

add 함수를 사용하면 (길이 자동 증가) 가장 끝에 추가되기 때문에 일반 배열보다는 편해요.

 

List<int> list=[1,2];
list[0]=5;
list.add(100);

 

where을 배우기 전에 퀴즈를 내보겠습니다.

List<String> list=["퍼스","유우","두령","돈령"];
list.where((name) => name.contains("령"));
print(list);

main내부의 이 코드를 돌리면 어떻게 나올까요? 

결과는  [퍼스, 유우, 두령, 돈령]이 그대로 나왔습니다. ["두령","돈령"]이 나올걸 기대하신 분도 있으시죠?

 

그럼 여기서 where을 배워봅시다. 여기의 where은 List의 매서드로 사용되었는데, 내부는 자바의 람다함수처럼 생겼습니다. 

where 안쪽은 for문 돌리듯 list의 길이만큼 돌아가는데, 좌측의 (name)부분에는 각 요소인 "퍼스", "유우", "두령", "돈령"

이 순서대로 들어갑니다.

그리고 우측에서 true 혹은 false라는 값을 반환해야 하는데 함수를 넣을 수도 있고, 그냥 true, false를 입력해도 잘 작동합니다. 저는 각 요소가 "령"이라는 요소가 포함하고 있는지 확인하기 위해 contains 함수를 사용했습니다.

포함되어 있다면 true, 틀리면 false를 반환합니다.

그리고, 가장 중요한 부분인데, true면 그 값은 남겨두고, false면 그 값을 없앱니다.

주의해야할 점은, 원본 list를 변경시키지 않고 이터러블을 반환합니다. 그래서 위에서 list를 출력하면 당연히 원본 list가 나오는 것이죠. (이터러블에 대한 설명은 패스합니다.)

 

그렇다면 이번에는 의도대로  ["두령","돈령"]이 나오도록 해보겠습니다. 어떻게 작성하면 될지 한번 생각해보세요.

 

void main() {
  List<String> list=["퍼스","유우","두령","돈령"];
  List<String> list2 = list.where((name) => name.contains("령")).toList();
  print(list2);
  runApp(const MyApp());
}

 

반환값이 이터러블이니, 그대로 담으려고 하면 오류가 나겠죠? toList()를 통해 형변환을 시켜준다는 점이 포인트인 것 같습니다. 이렇게 하고 실행을 시키면  ["두령","돈령"]이 나옵니다.

 

map, reduce, fold 함수는 한번씩 사용만 해보고 설명은 조금만 해볼게요.

(하다보니 자바에서 stream 사용하던게 생각나네요)

void main() {
  List<String> list=["퍼스","유우","두령","돈령"];
  List<String> list2 = list.map((e) => "힘세고 강한 $e",).toList();
  String list3 = list.reduce((v,e) => v+e[0]);
  String list4 = list.fold("초깃값", (p, e) => p +=e[1]);
  print(list2);
  print(list3);
  print(list4);

  runApp(const MyApp());
}

돌리면 결과값으로

 

[힘세고 강한 퍼스, 힘세고 강한 유우, 힘세고 강한 두령, 힘세고 강한 돈령]
퍼스유두돈
초깃값스우령령

 

이런식으로 나옵니다. 

map은 각 요소의 값을 변경할 수 있습니다. (원본을 변경시키진 않습니다.)

reduce와 fold는 비슷해 보이지만, fold는 초깃값이 있고 반환 타입을 요소의 타입과 다른 형태도 가능합니다.

reduce는 각 요소의 타입인 String을 반환합니다. (int면 int 반환)

int list4 = list.fold(0, (p, e) => p+=e.hashCode);

예를 들면 이런식으로 사용할 수 있습니다.

map, set은 넘어가고, null 관련 연산자를 살펴보겠습니다. (이 맵은 위의 함수가 아닌 타입 Map을 의미합니다.)

 

String a= null;

 

위 코드는 자바라면 문제가 없을 코드지만, dart는 다릅니다. (빨간줄 뜹니다)

null을 지정하고 싶다면 자료형 뒤에 ?를 붙여줘야 합니다.

String? a= null;

 

이런식으로 써줘야 합니다.

초기에는 null값이 안들어가더라도 나중에 null값이 들어갈 수 있다면 써줘야 합니다.

"null을 허용한다" 가 더 맞는 표현일 것 같네요.

특별한게 하나 더 있는데, 변수의 값을 변경할때 등호 앞에 ??를 붙이게 되면 그 값이 null일때만 변경이 됩니다.

void main() {
  String? a= null;
  a ??= "퍼스";
  a ??= "유우";
  print(a);
  runApp(const MyApp());
}

여기서는 색깔 차이가 나지 않지만, 개발도구에서는 "유우" 부분이 회색으로 보이고

The left operand can't be null, so the right operand is never executed. 라는 문구가 보입니다.

안드로이드 스튜디오는 a라는 변수가 null일 수 없다는걸 아는거죠.

 

다음으로 타입 비교 연산자를 살펴보겠습니다. 자바 다룰때는 instanceOf를 사용하여 타입을 비교할 수 있었는데

dart에서는 is를 통해 타입을 비교할 수 있습니다.

 

void main() {
  String? a= null;
  a ??= "퍼스";
  a ??= "유우";
  print(a is! int);
  print(a is String);

  runApp(const MyApp());
}

경험상 !는 보통 앞에 붙는데, dart의 is는 뒤에 붙여야 하더군요.

의미는 부정의 의미입니다. "a 는 int형이 아닙니까?" -> String 이므로 true 반환.

"a 는 String형 입니까?" -> String 이므로 true 반환.

 

또 익숙해 보이는 것들은 넘어가고.. 이번에는 typedef를 사용해 보겠습니다.

느낌상으로는 함수의 형태를 미리 정의해 놓고, 나중에 같은 형태의 함수라면 그대로 대입받아 사용할 수 있는 느낌? 입니다.

책에는 함수의 시그니처를 정의하는 값이라고 하는데, 저는 역시 쉽게 이해할 수 있는 말이 좋은 것 같습니다.

 

아, 지금까지는 main문 안에서 정의했는데, 이번 typedef는 불가능합니다. 

main문도 하나의 함수이기 때문에 함수 안에서 함수를 선언하려고 하니 안되는 것으로 보입니다.

main 밖에서 정의해보고 사용해보겠습니다.

typedef MyFunc= int Function(String s);

int getLength(String s){
  return s.length;
}

int gethashcode(String s){
  return s.hashCode;
}

void main() {
  MyFunc f = getLength;
  String me= "riddleus";
  print( f(me) );
  f = gethashcode;
  print( f(me) );

  runApp(const MyApp());
}

결과값은 8 이랑 355536027가 나왔습니다.

MyFunc 선언시 반환값은 int, 매개변수는 String으로 하나를 받도록 했습니다.

그리고 아래의 getLength 및 getHashcode 함수 또한 반환값은 int, 매개변수는 String으로 하나를 받습니다.

이렇듯, 같은 형태라면 마음대로 골라 쓸 수 있는 것입니다.

또한 다트에서는 함수가 값처럼 쓸 수 있다는 점에서 "일급 객체"라고 불린답니다.

 

기초 문법은 여기까지하고, 다음 글에서는 다트 객체지향 프로그래밍에서 자바와 다른 부분 위주로 짚고 넘어가겠습니다.

감사합니다~

'flutter 공부 기록소' 카테고리의 다른 글

Flutter 공부 기록 6  (0) 2023.06.18
Fluuter 공부 기록 5  (1) 2023.06.17
Flutter 공부 기록 4  (0) 2023.06.16
Flutter 공부 기록2  (0) 2023.06.14
Flutter 공부 기록1  (0) 2023.06.13