Flutter 캠프 7일차

은성·2025년 12월 2일

Flutter 본캠프

목록 보기
7/57
post-thumbnail

오늘의 내용

리눅스 명령어, Git 기초, 반복문, 컬렉션, 열거형(enum), 함수, 제너릭

리눅스 명령어

  • pwd

현재 디렉터리 전체경로 확인하는 명령어

  • ls
  • 하위 폴더 목록 확인하는 명령어

cd
디렉터리를 이동하는 명령어

  • 예시 cd Desktop > 데스크탑으로 이동

/user/사용자명

  • 맨처음 나오는 / : 루트(절대경로)

Git 기초

❓레포지토리 > 저장소

  • 최초에 올릴 때 (프로젝트 생성 후) - 터미널 명령어
  1. 깃 저장소 초기화 (’git init’)
    .git 폴더가 생김, git 관련된 구성 및 설정 파일들 모은 폴더

  2. Git add .

    스테이징 영역에 추가 > 파일 변경 사항 추적을 시작함

  3. Git commit -m “커밋메시지”

    스테이징 영역의 모든 파일을 브렌치에 기록함

  4. 저장소 연결

    깃 저장소 생성후 commit 이후 세줄 복사 하고 붙여넣기

  5. Git Push

  • 수정내역을 올릴 때
  1. git add.
    수정한 모든 파일을 다시 재저장함.

  2. git commint -m “두번째 커밋”

  3. git push origin main

반복문

  • 어떤 코드를 여러 번 반복해서 실행하기 위해 사용
for (var i = 0; i < 5; i++) {
	print('호');
}

for

  • 반복할 특정 작업의 반복 횟수가 명확할 때 사용
  • for (초기화식, 조건식, 증감식) { … }
String message = 'Dart 공부';
for (var i = 0; i < 5; i++) {
	message += '!';
}
print(message); // Dart 공부!!!!!

// for 오른쪽 옆에 있는 i 에는 for 문의 코드 블록이 1번 실행될 때마다 0 부터 4 까지의 정수가 차례대로 대입돼요.
  • 조건식이 참이면 증감식을 실행,for문의 코드 블록을 실행
  • 조건식이 거짓이면 for문을 빠져나옴

while

  • while (조건식) { … }
int count = 1;

while (count <= 5) {
	print('count : $count');
	count += 1;
}
/*
count : 1
count : 2
count : 3
count : 4
count : 5
*/
  • while 문의 코드 블록을 실행하기 전에 먼저 while 문의 조건식을 검사함
  • 조건식이 참이면 while 문의 코드 블록을 실행하고, 거짓이면 while문을 빠져나옴

do-while

  • do { … } while (조건식);
int count = 1;

do {
  print('count : $count');
  count += 1;
} while (count <= 5);
/*
count : 1
count : 2
count : 3
count : 4
count : 5
*/

int count = 6;

do {
  print('count : $count'); // count : 6
  count += 1;
} while (count <= 5);
count 가 6 이기 때문에 while 문의 조건식에 맞지 않아서 do 문의 코드 블록이 최초 1회만 실행돼요.
  • do문의 코드 블록을 우선 실햄함.
    while문에 있는 조건식이 참인지 거짓인지는 중요하지 않음.
    이후 while문의 조건식이 참이면 do문에 묶인 코드 블록을 다시 실행함, 조건식이 거짓이면 do문을 빠져나옴

for-in

  • for 문만 있는 형태의 초기화식에 있는 변수를 사용하지 않으면서,
    Collection (ex. List, Set, Map) 의 요소를 순회할 때 사용해요.
  • for (순회식) { … }
List<String> fruits = ['사과', '바나나', '귤'];

for (var fruit in fruits) {
  print(fruit);
}
/*
사과
바나나
귤
*/
  • in 의 오른쪽에 있는 콜렉션 데이터의 요소가 for 문을 돌면서 하나씩 in 의 왼쪽에 있는 변수에 대입
  • in 이 포함된 for 문의 오른쪽 옆에 있는 변수는 for 문의 코드 블록이 1번 실행되는 동안 값이 바뀌지 않기 때문에 상수로 선언가능함
List<int> numbers = [1, 2, 3];

for (final number in numbers) {
	print(number);
}
/*
1
2
3
*/

반복문에서 자주 사용하는 키워드

break

  • 반복문이 실행되고 있던 중에 이제 그만 실행하고 싶을 때
int count = 1;

while (count <= 6) {
  count += 1;
  if (count == 5) {
    print('count = $count'); // count = 5
    break;
  }
}

break 가 없으면 while 문의 코드 블록이 계속 실행돼서 print 문이 실행되지 않음

continue

  • 반복문 실행 중에 특정 조건인 경우에는 건너뛰고 싶을 때
final fruits = ['사과', '파인애플', '오렌지', '귤', '복숭아'];
for (final fruit in fruits) {
	if (fruit == '파인애플') {
		continue;
	}
	print('맛있는 $fruit');
}
/*
맛있는 사과
맛있는 오렌지
맛있는 귤
맛있는 복숭아
*/

주석

한줄 주석

//

// 이 줄은 컴파일러가 읽지 않아요.
int a = 3; // 이 줄은 컴파일러가 읽어요.

여러줄 주석

/**/

  • 컴파일러는 /**/ 사이에 있는 모든 것 무시
/*
이 모든 것은
컴파일러가 읽지 않습니다.
*/

문서 주석

/// or /**

  • 컴파일러는 /// 로 시작하는 줄에 있는 모든 것 무시
  • /// 를 여러 줄에 연속해서 쓰면 여러줄 주석 (/**/) 이랑 같은 기능
  • [] 를 주석에 포함할 수 있는데 코드의 특정 요소 (ex. 매개변수, 클래스, 메소드, 변수) 를 참조한 문서를 만들고 싶을 때 주석 안에 해당 요소를 [] 사이에 넣으면 돼요.
/// 이 함수는 두 숫자의 합을 반환합니다.
///
/// [a]와 [b]는 더해질 두 숫자입니다.
int add(int a, int b) {
  return a + b;
}

[a][b] 는 각각 add() 의 매개변수인 a 와 b 를 참조한다.
/// 이 클래스는 사용자의 정보를 담고 있습니다.
///
/// [User] 클래스는 [name]과 [age] 필드를 포함합니다.
class User {
  /// 사용자의 이름
  String name;

  /// 사용자의 나이
  int age;

  /// [name]과 [age]를 사용하여 새로운 [User] 객체를 생성합니다.
  User(this.name, this.age);
}

//[User] , [name] , [age] 는 각각 User 클래스, name 변수, age 변수를 참조한다.

컬렉션 (collections)

  • List, Set, Map

List

  • 순서가 있는 값들이 묶인 형태

List<[타입]> [변수 이름] = [요소];

List<int> numbers = [1, 2, 3, 4, 5];
각각의 요소는 , 로 구분한다.
  • 요소를 넣지 않고 쓰는 경우
List<int> numbers = [];
요소 없는 List도 만들 수 있음

[변수 이름] = [요소];

var numbers = [1, 2, 3, 4, 5];

List 요소에 변동이 있는 경우에는 var 로 선언해요.
이때 numbers 을 List<int> 타입으로 추론한답니다

final numbers = [1, 2, 3, 4, 5];
const names = ['Alice', 'Bob', 'Henry'];

List 요소에 변동이 없는 경우에는 final 이나 const 로 선언 가능 !!
numbers 를 List<int> 타입으로 추론하고,
names 를 List<String> 타입으로 추론해요.
  • 요소를 넣지 않고 쓰는 경우
var numbers = [];
var names = <String>[];
요소 없는 List도 만들 수 있음

특징

각각의 요소는 모두 같은 타입이어야함

  • Int에 String를 쓰면 오류남
    List 를 선언할 때 요소의 타입을 정해 주지 않은 경우에는
    List 안에 있는 요소들의 타입이 서로 달라도 됨
const fruits = ['사과', '파인애플', '오렌지', 8];
print(fruits.runtimeType); // List<Object>

String 과 int 의 상위 클래스인 Object 로 추론해요.
참고로, runtimeType 은 객체의 타입을 반환해 준답니다 !

//runtimeType : 앞에 있는 타입을 반환해주는 명령어

index

  • 각 요소에 접근할 수 있음
List<int> numbers = [1, 2, 3, 4, 5];
print(numbers[0]); // 1
  • index는 0 이상의 정수이고 , 첫번째 요소의 index는 0 이다.
    첫번째 요소의 indexrk 1dl dkslfksms rjtdp wndmlgodi gka.
    index에 음수를 넣으면 RangeError가 발생함

  • 요소를 바꿀 수 있음.

Index 를 통해 요소를 바꿀 수도 있어요.

var numbers = [1, 2, 3, 4, 5];
print(numbers[3]); // 4

numbers[3] = 2;
print(numbers[3]); // 2
  • 상수로 선언한 List 의 요소를 바꾸려고 하면 오류가 남
const numbers = [1, 2, 3, 4, 5];
numbers[3] = 2; // Unsupported operation: indexed set

length

  • 요소의 개수를 구할 수 있음
var fruits = ['사과
', '파인애플', '오렌지'];
print(fruits.length); // 3
print(fruits[fruits.length - 1]); // 오렌지

// -1 : 인데스는 0부터 시작하기때문에 사과가 0 파인애플이 1 오렌지가 2 : 3-1 =2 오렌지

isEmpty

  • List 에 요소가 없는지 (List가 비어있는지) 알 수 있음
var numbers = [];
print(numbers.isEmpty); // true
print(numbers.length); // 0
var fruits = ['사과
', '파인애플', '오렌지'];
print(fruits.isEmpty); // false

요소가 없으면 true를 요소가 있으면 false를 반환함

isNotEmpty

  • List 에 요소가 있는지 판별하는 친구
var numbers = [];
print(numbers.isNotEmpty); // false
var fruits = ['사과
', '파인애플', '오렌지'];
print(fruits.isNotEmpty); // true

요소가 있으면 true를 요소가 없으면 false를 반환함

indexOf()

  • 특정 요소의 Index 를 알 수 있음
var fruits = ['사과
', '파인애플', '오렌지'];
print(fruits.indexOf('파인애플')); // 1
print(fruits.indexOf('포도')); // -1

List에 없는 요서라면 -1을 반환함

add() , addAll()

  • 요소를 추가할 수 있음
var fruits = ['사과
fruits.add('복숭아');
print(fruits[3]); // 복숭아
', '파인애플', '오렌지'];
fruits.addAll(['포도', '귤']);
print(fruits); // [사과
, 파인애플,
오렌지, 복숭아, 포도,]
final additionalFruits = ['샤인머스켓', '수박'];
fruits.addAll(additionalFruits);
print(fruits); // [사과
, 파인애플,
오렌지, 복숭아, 포도,, 샤인
머스켓, 수박]

add() : 요소 하나만 추가할 때
addAll() : 여러 요소를 추가할 때 사용

remove() , removeAt()

  • 요소를 삭제할 수 있음
var fruits = ['사과
', '파인애플', '오렌지'];
fruits.remove('파인애플');
print(fruits); // [사과
,
오렌지]
var appleIndex = fruits.indexOf('사과');
fruits.removeAt(appleIndex);
print(fruits); // [오렌지]

remove() 는 삭제할 요소를 () 안에 넣으면 되고,
removeAt() 은 삭제할 요소의 Index 를 () 안에 넣으면 돼요.

clear()

  • 모든 요소를 삭제 할 수 있음
var fruits = ['사과', '파인애플', '오렌지'];
fruits.clear();
print(fruits); // []
print(fruits.isEmpty); // true
print(fruits.isNotEmpty); // false

Set

  • 중복되지 않은 값들이 묶인 형태

Set<타입> [변수 이름] = {요소};

Set<int> numbers = {1, 2, 3, 4, 5};
  • 요소를 넣지 않고 쓰는경우
    Set<int> numbers = {};

변수 이름 = {요소};

var numbers = {1, 2, 3, 4, 5};

Set 요소에 변동이 있는 경우에는 var 로 선언해요.
이때 numbers 를 Set<int> 타입으로 추론한답니다 !

final numbers = {1, 2, 3, 4, 5};
const names = {'Alice', 'Bob', 'Henry'};

Set 요소에 변동이 없는 경우에는 final 이나 const 로 선언 가능 !!
numbers 를 Set<int> 타입으로 추론하고,
names 를 Set<String> 타입으로 추론해요.
  • 요소를 넣지 않고 쓰는 경우
var names = <String>{};

요소 없는 Set 도 만들 수 있어요 🙂
  • List 처럼 var numbers = {}; 형태로 선언할 경우 numbers 는 Map 타입이 됨
var names = {};
print(names.runtimeType); // LinkedMap<dynamic, dynamic>

특징

각각의 요소는 모두 같은 타입이어야함

  • String에 Int를 쓰면 오류남
    Set 을 선언할 때 요소의 타입을 정해 주지 않은 경우에는
    그 Set 안에 있는 요소들의 타입이 서로 달라도 돼요.
var fruits = {'사과', '파인애플', '오렌지', 8};
print(fruits.runtimeType); // _HashSet<Object>

String 과 int 의 상위 클래스인 Object 로 추론해요.

요소들의 순서가 보장되지 않음

  • List 와 다르게 Index 라는 개념이 없음
var fruits = {'사과', '파인애플', '오렌지'};
print(fruits[2]); // Error: The operator '[]' isn't defined for the class 'Set<String>'.

Set 에 Index 를 적용하려고 하면 오류가 난답니다 !

중복시 하나를 제외하고 나머지는 무시함

var fruits = {'사과', '파인애플', '사과'};
print(fruits); // {사과, 파인애플}

오류가 나지는 않아요 ! 조용히 중복 값을 제거해 준답니다 ㅋㅋ

length

  • 요소의 개수를 구할 수 있음
var fruits = ['사과
', '파인애플', '오렌지'];
print(fruits.length); // 3
print(fruits[fruits.length - 1]); // 오렌지

// -1 : 인데스는 0부터 시작하기때문에 사과가 0 파인애플이 1 오렌지가 2 : 3-1 =2 오렌지

isEmpty

  • Set 에 요소가 없는지 (Set 이 비어있는지) 알 수 있어요.
var numbers = [];
print(numbers.isEmpty); // true
print(numbers.length); // 0
var fruits = ['사과
', '파인애플', '오렌지'];
print(fruits.isEmpty); // false

요소가 없으면 true를 요소가 있으면 false를 반환함

isNotEmpty

  • Set 에 요소가 있는지 판별하는 친구
var numbers = [];
print(numbers.isNotEmpty); // false
var fruits = ['사과
', '파인애플', '오렌지'];
print(fruits.isNotEmpty); // true

요소가 있으면 true를 요소가 없으면 false를 반환함

add() , addAll()

  • 요소를 추가할 수 있음
var fruits = ['사과
fruits.add('복숭아');
print(fruits[3]); // 복숭아
', '파인애플', '오렌지'];
fruits.addAll(['포도', '귤']);
print(fruits); // [사과
, 파인애플,
오렌지, 복숭아, 포도,]
final additionalFruits = ['샤인머스켓', '수박'];
fruits.addAll(additionalFruits);
print(fruits); // [사과
, 파인애플,
오렌지, 복숭아, 포도,, 샤인
머스켓, 수박]

add() : 요소 하나만 추가할 때
addAll() : 여러 요소를 추가할 때 사용

remove()

  • 요소를 삭제할 수 있음
var fruits = {'사과', '파인애플', '오렌지'};
fruits.remove('파인애플');
print(fruits); // {사과, 오렌지}

삭제할 요소를 () 안에 넣으면 돼요.
Index 개념이 없으니까 removeAt() 도 없겠죠 ?

contains(), containsAll()

  • 특정 요소가 있는지 알 수 있어요
var fruits = {'사과', '파인애플', '오렌지'};
print(fruits.contains('사과')); // true
print(fruits.contains('포도')); // false

print(fruits.containsAll({'사과', '오렌지'})); // true
print(fruits.containsAll({'사과', '귤'})); // false

contains() 는 하나의 요소가 포함되어 있는지 판별할 때,
containsAll() 은 여러 요소가 포함되어 있는지 판별할 때 사용해요.
containsAll()() 에 넣은 요소 중 하나라도 없으면 거짓으로 판별해요.

Map

  • 키와 값이 묶인 하나의 쌍으로 이루어진 형태

Map<key 타입, value 타입> 변수 이름 = {key: value};

Map<String, String> people = {'Alice': 'Teacher', 'Bob': 'Student'};
  • 요소를 넣지 않고 쓰는경우
Map<String, String> people = {};

변수 이름 = {key: value};

var people = {'Alice': 'Teacher', 'Bob': 'Student'};

Map 요소에 변동이 있는 경우에는 var 로 선언해요.
이때 people 은 Map<String, String> 타입으로 추론한답니다 !

final people = {'Alice': 'Teacher', 'Bob': 'Student'};
const animals = {'Dog': 3, 'Cat': 5};

Map 요소에 변동이 없는 경우에는 final 이나 const 로 선언 가능 !!
people 을 Map<String, String> 타입으로 추론하고,
animals 를 Map<String, int> 타입으로 추론해요.
  • 요소를 넣지 않고 쓰는경우
var people = {};

특징

키들과 값들은 타입이 같아야함.

Map 을 선언할 때 요소의 타입을 정해 주지 않은 경우에는
그 Map 안에 있는 키들의 타입과 값들의 타입이 각각 통일되지 않아도 됨

var people = {'Alice': 25, 45: 'Bob'};
print(people.runtimeType); // LinkedMap<Object, Object>
  • 키와 값을 서로 다른 타입으로 구성할 수 있음
Map<String, int> people = {'Alice': 25, 'Bob': 30};
키는 String 타입, 값은 int 타입이군요 !
  • 키는 중복될 수 없지만 , 값은 중복될 수 있음
Map<String, int> people = {'Alice': 25, 'Bob': 25, 'Alice': 23};
print(people); // {Alice: 23, Bob: 25}

‘Alice’ 키가 중복돼서 ‘Alice’ 키가 하나만 들어간 것을 볼 수 있어요.
하지만, 25 값은 중복되어도 괜찮아요.

length

  • 요소의 개수를 구할 수 있어요.
Map<String, int> people = {'Alice': 25, 'Bob': 30};
print(people.length); // 2

언뜻 보면 4개 같지만, 키와 값의 쌍이 하나라서 2개랍니다 !

isEmpty

  • Map 에 요소가 없는지 (Map 이 비어있는지) 알 수 있어요.
var names = {};
print(names.isEmpty); // true
print(names.length); // 0

var people = {'Alice': 25, 'Bob': 30};
print(people.isEmpty); // false

요소가 없으면 true, 요소가 하나라도 있으면 false 를 반환해요.

isNotEmpty

  • Map 에 요소가 있는지 판별하는 친구
var names = {};
print(names.isNotEmpty); // false

var people = {'Alice': 25, 'Bob': 30};
print(people.isNotEmpty); // true

요소가 하나라도 있으면 true, 요소가 없으면 false 를 반환해요.

[변수 이름][키 이름]]

  • 값을 검색할 수 있음
    키가 고유한 특성을 가지고 있기 때문
Map<String, int> people = {'Alice': 25, 'Bob': 30};
print(people['Alice']); // 25

List 의 Index 와 비슷한 형태로 생겼어요.
  • Map 에 없는 키를 넣으면 ?
Map<String, int> people = {'Alice': 25, 'Bob': 30};
print(people['Paul']); // null

null을 반환함

[변수 이름][키 이름]] = [값];

  • 키의 값을 수정할 수 있어요.
Map<String, int> people = {'Alice': 25, 'Bob': 30};
people['Alice'] = 28;
print(people); // {Alice: 28, Bob: 30}
print(people['Alice']); // 28

[변수 이름][키 이름]] = [값];

  • 새로운 키와 값의 쌍을 추가할 수 있어요.
Map<String, int> people = {'Alice': 25, 'Bob': 30};
people['Charlie'] = 35;
print(people); // {Alice: 25, Bob: 30, Charlie: 35}

remove()

  • 요소를 삭제할 수 있어요.
Map<String, int> people = {'Alice': 25, 'Bob': 30};
people.remove('Bob');
print(people); // {Alice: 25}
print(people['Bob']); // null

containsKey()

  • 특정 요소가 있는지 알 수 있어요.
Map<String, int> people = {'Alice': 25, 'Bob': 30};
print(people.containsKey('Alice')); // true
print(people.containsKey('Paul')); // false

keys

  • 모든 키들을 알 수 있어요.
Map<String, int> people = {'Alice': 25, 'Bob': 30};
print(people.keys); // (Alice, Bob)

values

  • 모든 값들을 알 수 있어요.
var students = {'Alice': 25, 'Bob': 30};
print(students.values); // (25, 30)

var teachers = {'Paul': 35, 'Henry': 37, 'Bella': 35};
print(teachers.values); // (35, 37, 35)

값은 중복될 수 있기 때문에 중복된 값들이 모두 출력돼요.

List 와 Set 의 차이점

차이점ListSet
순서 유,무OX
index 유,무OX
중복 허용 유,무OX

열거형

  • 여러개의 상수 값을 묶은 형태

enum

enum [열거형 이름] {요소}

enum Color { red, green, blue }

요소들을 한줄에 나열할 수도 있고,

enum Animal {
  cat,
  dog,
  tiger,
  elephant
}

여러 줄에 나열할 수도 있어요.

특징

  • 열거형 이름을 통해 열거형에 포함된 값에 접근할 수 있음
enum Color { red, green, blue }
var myFavoriteColor = Color.blue;
print(myFavoriteColor); // Color.blue

switch

  • 열거형에 포함된 값 각각을 다룰 수 있어요.
enum Color { red, green, blue }

var myFavoriteColor = Color.green;
var result = '내가 제일 좋아하는 색은 ';

switch (myFavoriteColor) {
  case Color.red:
    result += '빨간색';
  case Color.green:
    result += '초록색';
  case Color.blue:
    result += '파란색';
}

print(result); // 내가 제일 좋아하는 색은 초록색

switch 문은 하나의 값에 대해 나올 수 있는 경우를 모두 고려할 때 사용한다고 했잖아요 

if

enum Color { red, green, blue }

var myFavoriteColor = Color.green;
var result = '내가 제일 좋아하는 색은 ';

if (myFavoriteColor == Color.red) {
  result += '빨간색';
} else if (myFavoriteColor == Color.green) {
  result += '초록색';
} else if (myFavoriteColor == Color.blue) {
  result += '파란색';
}

print(result); // 내가 제일 좋아하는 색은 초록색

if문도 사용하지만 주로 switch 문을 쓴답니다

index

  • 열거형에 포함된 값이 열거형의 몇 번째에 있는지 알 수 있음
enum Color { red, green, blue }

print(Color.red.index); // 0
print(Color.green.index); // 1
print(Color.blue.index); // 2

열거형에 값이 나열되어 있는 순서대로 index 가 부여되고,
List 의 Index 체계와 마찬가지로 열거형도 첫번째 값의 index 가 0 이랍니다 !

values

  • 열거형에 포함된 값들을 알 수 있어요.
enum Color { red, green, blue }

var colors = Color.values;
print(colors); // [Color.red, Color.green, Color.blue]
print(colors[1]); // Color.green

colors 는 List<Color> 타입으로 추론돼요.

name

  • 열거형에 포함된 값의 이름을 알 수 있음
enum Color { red, green, blue }
print(Color.red.name); // red

언제씀?

  • 고정된 값이 집합을 정의할 때 사용함

Set과enum의 차이점

차이점Setenum
정의 후 값 추가 가능 여부OX
  • Setadd(),addAll()을 사용해야함
차이점Setenum
중복 오류 유,무OX
차이점Setenum
순서 유,무XO
  • Set에는 index 개념이 없지만, eunm에는 index 개념이 있음

함수

  • 특정 작업을 수행하는 코드 블록
    입력을 받아서 특정 작업을 수행하고, 그 작업에 대한 결과를 반환하는 코드 블록

구성 요소

  • 반환 타입
    함수가 반환하는 값의 데이터 타입
    함수가 값을 반환하지 않는 경우에는 void로 선언해요

  • 함수 이름
    함수를 실행시킬 때 사용함 (호출)

  • 매개 변수
    함수 내부로 전달되어 코드 블록에서 사용하는 값
    1개 이상 가질 수 있고, 개수에 제한이 없어요.

  • 실행할 코드
    함수가 호출되면 실행되는 코드 블록

  • 반환값
    함수의 코드블록이 실행된 후 반환되는 값
    결과값이라고 생각하면 됨

[반환 타입][함수 이름]([매개변수 타입][매개변수 이름]) { return [반환값]; }

void printName() {
	print('강미래');
}

함수 이름 : printName

bool isOddNumber(int number) {
	return number % 2 != 0;
}

반환 타입 : bool
함수 이름 : isOddNumber
매개변수 타입 : int
매개변수 이름 : number
반환값 : number % 2 != 0

bool isNull(int? number) {
	return number == null;
}

반환 타입 : bool
함수 이름 : isNull
매개변수 타입 : int?
매개변수 이름 : number
반환값 : number == null

int add(int a, int b) {
  return a + b;
}

반환 타입 : int
함수 이름 : add
매개변수 타입 : int, int
매개변수 이름 : a, b
반환값 : a + b

[함수 이름]([매개변수 이름]) { return [반환값]; }

  • 타입 추론이 가능하기 때문에 반환 타입과 매개변수 타입을 생략해도 되지만,
    Dart 공식 문서에는 추천하지 않는다고 되어 있어서 쓰지 않는게 좋음
printName() {
  print('강미래');
}

함수 이름 : printName

isOddNumber(number) {
	return number % 2 != 0;
}

함수 이름 : isOddNumber
매개변수 이름 : number
반환값 : number % 2 != 0

add(a, b) {
  return a + b;
}

함수 이름 : add
매개변수 이름 : a, b
반환값 : a + b

[반환 타입][함수 이름]([매개변수 타입][매개변수 이름]) ⇒ 반환값;

  • 반환값이 하나의 표현식으로 나타낼 수 있는 경우만 사용 가능 !!
bool isOddNumber(int number) => number % 2 != 0;

반환 타입 : bool
함수 이름 : isOddNumber
매개변수 타입 : int
매개변수 이름 : number
반환값 : number % 2 != 0

int multiply(int a, int b) => a * b;

반환 타입 : int
함수 이름 : multiply
매개변수 타입 : int, int
매개변수 이름 : a, b
반환값 : a + b

호출법

  • 함수 이름을 가지고 호출하면 된다.
void printName() {
  print('강미래');
}

printName(); // 강미래

bool isOddNumber(int number) {
	return number % 2 != 0;
}

bool isTwoOddNumber = isOddNumber(2);
print(isTwoOddNumber); // false

int add(int a, int b) {
  return a + b;
}

int sum = add(2, 4);
print(sum); // 6

void main() {....}

  • main()
    모든 프로그램은 실행을 시작하기 위한 함수 (최상위 함수)를 반드시 가져가야 함.
    Dart 에서는 main() 함수가 그 역할을 함

특징

  • main() 함수의 코드 블록 안에 코드를 넣어야 코드가 실행됨
    main()안에 코드를 넣지 않으면 실행되지 않음

장점

  • 특정 작업을 수행하는 코드를 하나의 함수로 만들고,
    작업을 수행해야 하는 곳 마다 함수를 호출 하도록 하면 같은 코드를 여러 번 쓰지 않아도 돼서 효율적인 코드를 짤 수 있음.
void main() {
	int one = 1;
	int two = 2;
	print(one + two); // 3
	
	int three = 3;
	int four = 4;
	print(three + four); // 7
	
	int five = 5;
	int six = 6;
	print(five + six); // 11
	
	int seven = 7;
	int eight = 8;
	print(seven + eight); // 15
}

함수로 만들지 않은 코드

void printSum(int a, int b) {
	print(a + b);
}

void main() {
	printSum(1, 2); // 3
	printSum(3, 4); // 7
	printSum(5, 6); // 11
}

함수로 만든 코드

제너릭

  • 클래스나 함수에서 데이터 타입을 일반화 하여 다양한 타입을 지원할 수 있게 하는 기능

[타입 파라미터][함수 이름]<타입 파라미터>([매개변수]) { … }

  • 특정 타입에 의존하지 않고, 여러 타입에 대해 동일한 코드를 적용할 수 있어서 재사용성 높은 코드를 작성할 수 있음
int getFirstNumber(List<int> numbers) {
  return numbers[0];
}

String getFirstWord(List<String> words) {
  return words[0];
}

void main() {
  var numbers = [0, 1, 2, 3];
  print(getFirstNumber(numbers)); // 0
  
  var words = ['a', 'b', 'c'];
  print(getFirstWord(words)); // a
}

제너릭 사용하지 않은 함수

T getFirstElement<T>(List<T> list) {
  return list[0];
}

void main() {
  var numbers = [0, 1, 2, 3];
  print(getFirstElement(numbers)); // 0
  
  var words = ['a', 'b', 'c'];
  print(getFirstElement(words)); // a
}

제너릭 함수로 만들어서 사용한 코드

0개의 댓글