[Dart 기초] 자료형, 함수

지은·2023년 10월 16일
0

Dart/Flutter

목록 보기
2/5

기본 자료형

void main() {
  num a = 1.234;       // 숫자
  int b = 1;           // 정수
  double c = 11.11;    // 부동 소수점 숫자
  String name = '지은'; // 문자열
  bool isAdult = true; // 참 또는 거짓
  List<int> numberList = [1, 2, 3]; // 배열
  Map<String, int> person = {'age': 20, 'money': 10000}; // Map
  Set<String> colorSet = {'red', 'orange', 'yellow'};    // Set
}

List

void main() {
  List<Map<String, Object>> players = [
    {'name': '지은', 'xp': 999},
    {'name': '지지', 'xp': 1}
  ];
}

collection if

: Dart의 리스트에 요소를 조건부로 추가할 수 있게 해주는 간편한 방법

void main() {
  bool giveMeFive = true;
  var numbers = [1, 
                 2, 
                 3, 
                 4,
                 if(giveMeFive) 5
                ];
                
  print(numbers); // [1, 2, 3, 4, 5]
}

collection for

리스트를 생성할 때 루프나 반복문을 사용해 간단하게 요소를 추가하는 방법

void main() {
  var oldFriends = ['지은', '지지'];
  var newFriends = [
    '벨라',
    '홍시',
    for(var friend in oldFriends) '🤍 $friend'
  ];
  
  print(newFriends); // [벨라, 홍시, 🤍 지은, 🤍 지지]
}

$${}

Dart 문자열 내에서 변수와 표현식을 삽입려면 $${}을 사용한다.
$는 단순한 변수를 문자열에 삽입하는 데 사용되며, ${}는 변수와 표현식을 복잡한 문자열 중에 포함시키는 데 사용된다.

void main() {
  var name = '지은';
  var age = 10;
  var greeting = 'Hello, my name is $name and I am ${age + 2}!';

  print(greeting); // Hello, my name is 지은! and I am 27!
}

collection ifcollection for를 둘 다 사용한 예시

void main() {
  bool giveMeFive = true;
  var numbers = [
    for (int i = 1; i <= 4; i++) i,
    if (giveMeFive) 5,
  ];
  
  print(numbers); // [1, 2, 3, 4, 5]
}

Map

: 키(key)와 값(value) 쌍으로 데이터를 저장하는 데이터 구조

Map 생성하는 법

void main() {
  Map<String, dynamic> players = {
    'name': '지은',
    'xp': 20,
    'isAdult':  true,
  };
  // 맵의 키는 String 타입, 값은 dynamic 타입
  
  Map<int, List<bool>> mapExample = {
    1: [true, false],
    2: [false, false],
    3: [true, true],
  };
  // 맵의 키는 int 타입, 값은 Bool을 요소로 갖는 List 타입
}

Map 요소에 접근하는 법

var playerName = player['name']; // '지은'
var playerXP = player['xp']; // 20

Map 요소의 값 업데이트하는 법

player['isAdult'] = fase;

Set

: 고유한 값을 저장하는 데이터 구조로, 중복된 값을 허용하지 않는다.

Set 생성하는 법

void main() {
 Set<int> numberSet = {1, 2, 3, 4};
  
 numberSet.add(1);
 numberSet.add(1);
 numberSet.add(1);
  
 print(numberSet); // {1, 2, 3, 4} 중복된 값은 무시된다.
}

Set에 값 추가, 제거하는 법

numberSet.add(1);
numberSet.remove(1);

함수

Dart 함수는 반환 타입, 함수 이름, 매개 변수, 함수 본문으로 구성된다.
함수의 이름 앞에는 함수가 리턴하는 값의 타입을 적어줘야 한다. 아래 예시에서 void는 아무것도 리턴하지 않는다는 뜻이다.

또한 매개변수에도 타입을 지정해줘야 한다. 아래 예시는 문자열(String) 타입의 name 매개변수를 받고 있다.

void sayHello(String name) { // 아무 것도 리턴하지 않는 함수
  print('Hello $name!');
}

void main() {  
  sayHello('지은'); // 함수 호출 | 'Hello 지은!'
}

아래처럼 만약에 문자열을 리턴한다면, String을 리턴하는 함수라고 명시해줘야 한다.

String sayHello(String name) { // 문자열을 리턴하는 함수
  return 'Hello $name!';
}

void main() {  
  print(sayHello('지은')); // 'Hello 지은!'
}

화살표 함수 (Fat Arrow Function)

Dart는 화살표 함수 표기법을 제공하여 함수를 간결하게 작성할 수 있다.
return 구문과 중괄호({})를 생략하고 화살표(=>)를 사용하면 된다.

String sayHello(String name) => 'Hello $name!';

void main() {
  print(sayHello('지은')); // 'Hello 지은!'
}

명명된 인자 (Named Arguments)

함수 호출 시, 명명된 인자를 사용하여 인자의 순서를 신경 쓰지 않고 전달할 수 있다.
또한 명명된 인자를 사용하면 가독성이 높아지며, 자동 완성 기능도 사용할 수 있다.
명명된 인자를 사용하려면 함수의 파라미터를 중괄호 {}로 감싸면 된다.

String sayHello({
  required String name, 
  required int age, 
  required String country
}) {
    return 'Hello $name! You are $age, and come from $country.';
}

void main() {
  print(sayHello(
    country: 'Korea',
    name: '지은',
    age: 27,
  )); // Hello 지은! You are 27, and come from Korea.
}

null safety로 인해 에러가 뜨므로 required modifier를 붙여준다.
required는 해당 인자가 필수임을 나타낸다.

또는 기본값(default value)을 지정할 수 있다.
이는 함수 호출 시 해당 인자가 전달되지 않을 경우, 기본값을 사용하게 한다.

String sayHello({
  String name = 'defaultName', 
  int age = 0, 
  String country = 'defaultCountry'
}) {
  return 'Hello $name! You are $age, and come from $country.';
}
  
void main() {
  print(sayHello()); // Hello defaultName! You are 0, and come from defaultCountry.
}

선택적 위치 매개변수 (Optional Positional Parameters)

선택적 위치 매개변수는 함수의 파라미터 중 일부 파라미터가 선택적으로 값을 가질 수 있음을 나타내는 방법이다. 선택적 위치 매개변수는 함수를 호출할 때 인수를 전달하지 않아도 기본값을 가지고 있다.
선택적 위치 매개변수를 사용하려면 매개변수를 대괄호 []로 감싸고 필요한 경우 기본값을 주면 된다.

void main() {
  String sayHello(
    String name,
    int age,
    [String country = 'defaultCountry']
  ) => 'Hello $name! You are $age, and come from $country.';

  print(sayHello('지은', 27)); // Hello 지은! You are 27, and come from defaultCountry.
  print(sayHello('지은', 27, 'Korea')); // Hello 지은! You are 27, and come from Korea.
}

연산자(Opeartors)

String capitalizeName(String? name) {
  if (name != null) {          // name이 null이 아니라면
    return name.toUpperCase(); // name.toUpperCase()를 리턴한다.
    }
  return 'NAME'; // if 조건문에 들어가지 않은 경우, 'NAME'을 리턴한다.
  }

void main() {
  print(capitalizeName('jieun')); // JIEUN
  print(capitalizeName(null));    // NAME
}

삼항 연산자(?:)

위의 코드를 삼항 연산자를 사용하면 간단하게 아래처럼 표현할 수 있다.
삼항 연산자는 조건문을 간결하게 표현하는 방법으로 조건 ? 조건이 참인 경우 실행할 표현식 : 조건이 거짓인 경우 실행할 표현식으로 구성된다.

String capitalizeName(String? name) => name != null ? name.toUpperCase() : 'NAME';
// name이 null이 아닌 경우 name.toUpperCase()를 반환하고, 그렇지 않으면 'NAME'을 반환한다.

void main() {
  print(capitalizeName('jieun')); // JIEUN
  print(capitalizeName(null));    // NAME
}

Null-aware 연산자(?.)

Null-aware 연산자는 ?.로 표시되며, 객체가 null이 아닌 경우에만 해당 객체에서 메서드를 호출하거나 속성에 접근할 수 있게 한다.
객체가 null이면 예외를 발생시키지 않고 null을 반환한다.

String capitalizeName(String? name) => name?.toUpperCase() ?? 'NAME';

void main() {
  print(capitalizeName('jieun')); // JIEUN
  print(capitalizeName(null));    // NAME
}

?? 연산자 (Null Coalescing Operator)

좌항이 null인 경우에 우항의 값을 반환하는 연산자
주로 기본값을 설정하거나, 값이 null인 경우 대체값을 제공하는 데 사용한다.

String name = null;
String result = name ?? 'defaultName';
print(result); // 'defaultName'

??= 연산자 (Null-aware Assignment Operator)

좌항이 null인 경우에 우항의 값을 좌항에 할당하는 연산자
좌항에 이미 값이 있거나 null이 아니면 할당하지 않는다.
변수에 기본값을 설정하거나, 변수가 아직 초기화되지 않았을 때 초기값을 제공하는 데 유용하다.

void main() {
  String? name;     // 초기값은 null
  name ??= 'jieun'; // name이 null이므로 'jieun'이 할당된다.
  print(name);      // jieun
  
  name ??= 'GG';    // name에 이미 값이 있으므로 할당되지 않는다.
  
  print(name);      // jieun
}

typedef (Type Definition)

typedef데이터 유형에 별칭(alias)를 불여줄 수 있게 해준다.
이는 기존 데이터 유형을 다른 이름으로 참조할 수 있게 해주므로 코드를 더 읽기 쉽게 만들고, 복잡성을 줄이며, 코드를 재사용하고 유지 관리하기 쉽게 만들어준다.

TypeScript의 Interface랑 비슷한 개념같지만, Dart에서는 이 별칭을 함수 유형과 데이터 유형에 모두 사용할 수 있다.

typedef ListOfInts = List<int>; // List<int> 의 별칭을 ListOfInts로 정의

ListOfInts reverseListOfNumbers(ListOfInts list) { // List<int> 대신 사용
  var reversed = list.reversed;
  return reversed.toList();
}

void main() {
 print(reverseListOfNumbers([1,2,3])); // [3,2,1]
}
profile
개발 공부 기록 블로그

5개의 댓글

comment-user-thumbnail
2023년 10월 26일

오랜만에 보니까 기억이 새록새록이네요 ㅎㅎ
Map set이 그렇게 헷갈렷던 기억도 함께……ㅠㅠㅎㅎ
잘 보고 갑니당!

답글 달기
comment-user-thumbnail
2023년 10월 29일

자바스크립트랑 비슷하면서 다른느낌이네여 새로운 개념 잘보고 가용

답글 달기
comment-user-thumbnail
2023년 10월 29일

그래도 JS랑 비슷해서 사용해보진 않았지만 익숙한 느낌이네요 ㅎㅎ

답글 달기
comment-user-thumbnail
2023년 10월 29일

오랜만에 보니 다트를 배웠던 게 새록새록,, 잘 복습하고 가요

답글 달기
comment-user-thumbnail
2023년 10월 30일

비교해서 설명해주니 쏙쏙 잘 들어옵니다 !

답글 달기