flutter

Dart 문법 정리

테오구 2022. 6. 18. 22:48
728x90

내가 보고 공부하려고 정리하는 Dart문법!

 

dart 문법 매뉴얼과 flutter 생존 코딩 공부 책을 보면서 정리.

dart.dev/guides/language/language-tour

 

A tour of the Dart language

A tour of all of the major Dart language features.

dart.dev

 

실습 가능한 웹 IDE 환경 : dartpad.dev/

 

DartPad

 

dartpad.dev

 

기본 문법

(티스토리 코드블럭은 Dart를 지원하지 않아 우선 java로 표기합니다)

 

주석

 
//주석
 
 
 
/**
 
* 주석
 
**/
 
 
 
/// 문서주석

 

문장

명령 단위. 세미콜론 ;으로 끝난다.

 

변수

data를 담는 상자. 종류는 type, 자료형이라고 함.dart는 int, double, String, bool을 기본 제공.사용자가 직접 타입을 정의할 수 있음.

 
String name;
 
name = "홍길동";
 
name = '홍길동';
 
//따옴표 종류 상관없이 가능

int, double은 num type의 하위 집합이라 int, double 대신 num으로 선언 가능.

num 타입에는 int, double 대입 가능.

 
int a = 1;
 
double b = 2.0;
 
 
 
num c = a;
 
c = b;

 

타입 추론

위와 같이 type을 직접 명시하지 않고, var로 대체할 수 있음. (JS같이)

일반적으로 많이 사용.

 
var i = 10; //int
 
var d = 10.0 //double
 
var s = "hello"; //String
 
var b = true; //boolean

 

상수 final, const

값이 변하지 않는 경우는 상수 사용. 선언시 final을 제일 앞에 붙이면 값이 수정되지 않음. 타입 생략 가능.

 
final String name = "홍길동";
 
final name = "홍길동";

 

산술 연산자

+, -, *, /(나누기 - double), ~/(몫 - int), %(나머지 - int) 사용 가능.

+의 경우 string concat에서도 사용.

 

증감 연산자

1씩 증가(++) 또는 1씩 감소(--). 후위(식++)/전위(++식) 연산 모두 가능.

 

비교 연산자

==, !=, >, <, >=, <= 사용 가능.

 

논리연산자

boolean 타입으로 결과 반환.

&&, ||, ==, !, != 사용 가능.

 

타입 검사

is를 사용. 

[변수] is [type] => 같은 타입인지[변수] is! [type] => 다른 타입인지

 
int a = 1;
 
 
 
if (a is int){~}
 
if (a is! int){~}

 

형변환 (as)

type casting. as를 사용. 다른 타입끼리는 변환 불가. 상위 개념으로만 변환 가능.

특히, int, double은 num으로 묶여있지만 각자는 관계가 없어 형변화 불가.

 
var c = 10.0
 
num n = c as num;
 
num n = c //as num 생략 가능
 
int d = c as int; //errpr

 

 

함수

function. 코드 묶음 단위.

 

함수 형태

입력 받는 문자 : 매개변수 parameter실제로 입력받는 값 : 인수 argument반환되는 값 : 반환값 Return

=> 일반적인 C문법과 동일하다.

 

변수 앞에 $를 붙여 문자열 내에 변수 삽입 가능. (파이썬에서 {}사용하는 것과 같다)

또한, ${~~}부분에 표현식 사용 가능.

 
String name = "이순신";
 
int age = 20;
 
 
 
void main(){
 
print('$name은 $age살 입니다.');
 
print("$name은 ${name.length}글자 입니다.");
 
}

 

함수와 메서드

최상위 함수 : class 밖에 작성하는 함수. 일반적으로 말하는 함수들. (main method처럼 가장 밖에 작성). 어디에서나 호출 가능.

method : class 내부에 작성하는 함수. 정의된 class에 관계된 기능을 수행. Static이 붙은 method는 정적 메서드가 되어 최상위 함수처럼 사용 가능.

 

익명 함수

anonymouse function. 

([인수명]) { [동작 or Return 값] }

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

 

람다식

([인수명]) => [동작 or Return 값]

(number) => number%2 == 0;

 

선택 매개변수

정의에서 {}로 감싼 매개변수는 선택적으로 사용 가능. Named parameter.

void f(String name, {int age}) {}

{}로 감싸지 않은 매개변수를 필수적으로 넘겨주어야 하고, {}로 감싼 매개변수에 값을 주고 싶다면 반드시 매개변수의 이름을 붙여서 age : 5로 넘겨주어야 한다.

선택 매개변수는 기본값 지정이 가능하다.

void f(String name, {int age = 5}) {}

 

 

분기와 반복

if else

 
int a = 10;
 
 
 
if (a % 2 == 0) {~}
 
else if (a % 3 == 0) {~}
 
else {~}

 

삼항 연산

[조건] ? [참일 때] : [거짓일 때]

var number = a%2 ? a++ : a--

 

switch case

조건에 맞는 값이 여러 개일 때 유용. enum과 함께 사용할 땐 모든 케이스를 검사해야 하는 강제성이 생김.

Switch - case - break로 문법은 C와 동일

 

for

요소를 반복.

 
for (var i = 0; i < 10 ; i++){
 
print(i);
 
}

 

 

 

객체 지향 프로그래밍

dart는 객체지향 프로그래밍 언어!

 

클래스

객체 object : 저장 공간에 할당되어 값을 가지거나 식별자에 의해 참조되는 공간. (변수, 함수, 메서드)

인스턴스 instance : 객체를 메모리에 작성하는 것.

클래스 class : 인스턴스의 설계도. 

속성 property : 클래스 안에 표현되는 속성.

 

클래스는 일종의 사용자 정의 타입!

 
class Person{
 
String name;
 
int age;
 
}
 
 
 
var person = new Person();
 
var person2 = Person(); //new 생략 가능

변수명 뒤에 . 연산자를 입력, 객체의 property에 접근 가능.

 
print(person.name);
 
print(person.age);

메서드 : 클래스 안에 작성하는 함수. 메서드는 class의 프로퍼티를 조작하는 등의 용도로 사용. 이 역시 .연산자를 붙여 접근 가능.

 

접근 지정자

java에서의 public, private와 같은 역할. 여기서는 _ 을 붙여 구분한다. (붙이면 private)

 
class Person{
 
String name;
 
int _age;
 
 
 
void addOneYear(){
 
_age++;
 
}
 
}
 
 
 
//=====다른 Dart file
 
import 'person.dart';
 
 
 
void main(){
 
var person = Person();
 
person._age = 10; //error!
 
}

이때, private의 영역은 정의된 파일 내! 즉, _이 붙어 있어도 같은 파일 내라면 class의 밖에 있어도 자유롭게 접근이 가능하다.

 

생성자

인스턴스화 하는 방법을 제공하는 일종의 메서드. 인스턴스가 생성될 때 가장 먼저 생성됨. 메서드 이름은 클래스명과 같다.

 
class Person{
 
String name;
 
int _age;
 
 
 
Person({this.name, this._age}); //constructor
 
}
 
 
 
var person = Person();
 
var person2 = Person(name : '홍길동', _age : 20);

 

 

getter, setter

_을 붙인 private 변수에 외부에서 접근하기 위해 만들어주는 통로같은 메서드.

 
//person.dart
 
 
 
class Person{
 
String name;
 
int _age = 10;
 
 
 
int get age => _age; //getter
 
set setAge(num value) => _age = value; //setter
 
}
 
 
 
//main.dart
 
 
 
void main(){
 
var person = Person();
 
print(person.age); //10
 
person.setAge = 5;
 
print(person.age); //5
 
}

 

상속

implement. 주는 쪽이 super class (부모), 받는 쪽이 sub class(자식)

 
//부모 class
 
class Hero{
 
String name = 'hero';
 
 
 
void run() {}
 
}
 
 
 
//위를 상속받은 자식 클래스
 
class SuperHero extend Hero{
 
@override //재정의
 
void run(){
 
super.run(); //부모의 run실행
 
this.fly(); //추가로 자식이 따로 정의한 fly도 실행.
 
}
 
 
 
void fly() {}
 
}
 
 
 
 
 
void main(){
 
var hero = SuperHero();
 
hero.run();
 
hero.fly();
 
print(hero.name); //hero 출력
 
}

 

추상 클래스

abstract class. 추상 메서드를 포함하는 클래스.

추상 메서드 : 선언만되고 정의가 없는 메서드.

추상 클래스는 다른 클래스에서 implement해서 완성하는 상속 재료로 사용된다. (틀같은 느낌? 템플릿?)

이때 대상 클래스에는 implements, 메서드에는 @override 키워드 사용(

여러 추상 클래스를 한번에 implement할 수도 있고, 추상 클래스를 구현할 때는 모든 추상 메서드를 재정의 해야 한다.

 
abstract class Monster{
 
void attack();
 
}
 
 
 
abstract class Flyable{
 
void fly();
 
}
 
 
 
class Bat implements Monster, Flyable(
 
@override
 
void attack(){
 
print('할퀴기!');
 
}
 
 
 
@override
 
void fly(){
 
print('펄럭펄럭');
 
}
 
}

 

믹스인

mixin. with를 사용하면 상속하지 않고 다른 클래스 기능 overwritte가능. 

 
class Goblin implements Monster{
 
@override
 
void attack(){
 
print('고블린 공격');
 
}
 
}
 
 
 
class DarkGoblin extends Goblin with Hero{
 
 
 
} //다크 고블린은 고블린이기도 하며, 히어로이기도 하며, 몬스터이기도 함. => 다형성!

 

열거형

enum type. 상수를 정의하는 특수한 형태의 클래스. 상수처럼 사용이 가능하다.

 
enum Status { login, logout }
 
 
 
var authStatus = Status.logout;
 
 
 
switch(authStatus){
 
case Status.login:
 
print('login');
 
break;
 
case Status.logout:
 
print('logout');
 
break;
 
}

 

 

컬렉션

list, map, set등의 collection을 기본 제공함.

 

List

순서가 있는 자료를 담음. Dart는 배열 (Array)를 별도로 제공하지 않는다.

 
List<String> items = ['a', 'b', 'c'];
 
var items = ['a', 'b', 'c'];
 
 
 
items[0] = 'd'; //0부터 시작하는 index.
 
 
 
print(items.length); //3
※ dynamic
모든 타입을 대변하는 특수 타입! 여러 타입을 한 리스트에 넣거나 일반 변수를 선언할 때도 사용 가능.

List<dynamic> list = [1, 2, 'a'];
var list = [1, 2, 'a'];

 

스프레드 연산자

spread. '...' 연산자. 컬렉션을 펼쳐준다. 다른 컬렉션 안에 컬렉션을 삽입할 때 사용.

 
var items = ['a', 'b', 'c'];
 
 
 
var items2 = ['d', ...items, 'e']; //d, a, b, c, e

 

Map

순서 없음. 탐색 빠른 자료구조. key-value의 쌍.

 
//Map<String, String> cityMap = {...} 과 같음.
 
var cityMap = {
 
'korea': 'busan',
 
'japan': 'tokyo',
 
'china': 'Beijing'
 
};
 
 
 
cityMap['korea'] = 'seoul';
 
 
 
print(cityMap.length); //3
 
 
 
cityMap['America'] = 'Washington'; //새 값 추가

 

Set

집합 표현. => 중복 불허용

add(), remove()로 추가/삭제 가능.

contains() : 찾는 자료가 집합에 있는지 없는지 bool로 반환.

 
// Set<String> citySet = {}과 같음
 
var citySet = {'서울', '부산', '광주', '대전', '울산'}
 
 
 
citySet.add('대구');
 
citySet.remove('서울');
 
 
 
print(citySet.contatins('울산'); // true

비어있는 Set이나 map을 작성할 때는 주의! 그냥 {}만 쓰면 Map으로 인식해버림.

 
var mySet = <String>{}; //set으로 인식
 
var mySet2 = {}; //dynamic, dynamic인 map으로 인식

 

 

함수형 프로그래밍

Dart는 객체지향 프로그래밍과 함수형 프로그래밍의 특징을 모두 제공 (뭐지....)

함수형 프로그래밍 : 자료 처리를 수학적 하수의 계산으로 취급하는 패러다임. (상태와 가변 데이터 X)

 

일급 객체

함수를 값으로 취급. 즉, 다른 변수에 함수를 대입할 수 있음.

 
void greeting(String text){
 
print(text);
 
}
 
 
 
void main(){ // 함수를 다른 변수에 대입할 수 있음
 
var f = greeting;
 
f('hello');
 
}

다른 함수의 인수로 함수 자체를 전달하거나 함수를 반환받을 수도 있음.

함수를 매개변수로 전달, 수정, 변수에 대입하기가 가능한 객체를 '일급 객체', first-class object라고 함.

 

for문과 forEach()함수

for : 외부 반복

forEach() : 내부반복 =>(E element) {} 형태의 함수를 인수로 받음.

 
items.forEach(print); // 1, 2, 3, 4, 5
 
 
 
items.forEach((e) {
 
print(e);
 
});
 
 
 
itmes.forEach((e) => print(e));
 
 
 
items.forEach(print);

 

where

조건을 필터링 할 때 사용. 함수형 프로그래밍을 지원하는 함수들은 결과를 반복 가능한 타입으로 반환하여 메서드 체인으로 연결해서 사용 가능.

items.where((e) => e % 2 == 0).forEach(print); //2, 4

 

map

반복되는 값을 다른 형태로 변환하는 방법을 제공.

items.where((e) => e % 2 == 0).map((e) => '숫자 $e').forEach(print);

 

toList

함수형 프로그래밍을 지원하는 함수 대부분은 Iterable<T> 인터페이스 타입 인스턴스를 반환.

하지만 실제 사용할 때는 대부분 리스트 형태로 변환해야 하는 경우가 많음. => 결과를 리스트로 바꿔야함.

final result = itmes.where((e) => e % 2 == 0).toList();

 

toSet

리스트에 중복된 데이터가 있을 경우, 중복을 제거한 리스트를 얻고 싶을 때 집합인 set을 사용.

final result = itmes.where((e) => e % 2 == 0).toSet().toList();

 

any

리스트에 특정 조건을 충족하는 요소가 있는지 없는지 검사할 때 사용하는 함수.

print(items.any((e) => e % 2 == 0));

 

reduce

반복 요소를 줄여가면서 결과를 만들 때 사용하는 함수.

 
// 최댓값을 구할 때, 순차적으로 비교하는 로직
 
 
 
final result = items.reduce(max); //5

 

 

기타

계단식 표기법 .. 연산자

cascade notation .. 연산자. 동일 객체에서 일련의 작업을 수행 가능.

.. 연산자를 사용하면 메서드를 수행한 객체의 참조를 반환.

 
print(items
 
..add(6)
 
..remove(2)); //1, 3, 4, 5, 6

 

컬렉션 if

조건에 의해 컬렉션의 값을 조정하거나 다르게 사용하고 싶을 때 사용.

 
bool promoActive = true;
 
 
 
print([1, 2, 3, 4, 5, if (promoActive) 6]); // true일 때만 6이 추가됨

 

컬렉션 for

컬렉션 문법 안에서 for 문을 사용 가능.

 
var listOfInts = [1, 2, 3];
 
var listOfStrings = [
 
'#0',
 
for (var i in listOfInts) '#$i'
 
];
 
//#0, #1, #2, #3

 

null 처리

다트는 null을 처리할 수 있는 여러가지 방법을 제공. (Dart에서는 모든 것이 객체. int, double, bool 같은 타입들도 모두 객체라 null값을 가질 수도 있음.)

?. 연산자를 사용하면 null 여부 파악 가능.

print(name?.lentgh); //null출력

 

??연산자는 객체가 null일 때 작동을 간단히 구현하는데 사용.

print(name?.length ?? 0); //name이 null이면 0을 출력
 

출처: https://at0z.tistory.com/155 [💾:티스토리]

728x90

'flutter' 카테고리의 다른 글

라이프 사이클  (0) 2022.11.09
bottomnavigationbar를 유지하는 방법  (0) 2022.10.28