기본 dart 문법
VARIABLES
1. 변수 선언 방법
var name = "jh" 또는
String name = "jh"
으로 선언 할 수 있는데 보통 지역 변수선언할 때 var를 사용한다. 그리고 변수가 선언 되면 같은 해당 변수명의 값을 바꿔줄 수 있는데 이때는 같은 타입의 데이터로만 바꿀 수 있다.
var가 아닌 데이터 타입으로 선언할 때는 보통 class에서의 property에 쓰인다. 이건 나중에 강의 더 보면 이해 될 듯 하다.
2. dynamic type
다이나믹 타입은 var name; 으로 해버리면 해당 변수의 값의 타입에는 무엇이든 올 수 있다. 보통 잘 안쓰지만 꼭 필요할때가 있다고 한다. 값을 받아올 때 해당 타입이 어떤 것인지 모를 때, if(name is String) { ~~~ } 하는식으로 써먹으면 될 듯하다.
3. nullable
기본적으로 변수를 선언할 때 null값은 못받는 걸로 되어 있다.
String name = "jh"
name = null
은 문제가 된다. 하지만 여기서 String? name = "jh"와 같이 ?를 타입 뒤에 붙여주면 null값을 받을 수 도 있다는 뜻이다. api data 를 받아올 때 조건문식으로 쓰면 된다. name?.xxx 하면 name의 값이 null이 아니라면 xxx 한다라는 조건문이다.
4. final
final name = "jh" 하면 해당 name 변수는 나중에 값을 바꿀 수 없다. js의 const와 똑같은 기능이라 보면 된다.
5. late
api data를 받아오는 data fetching때 매우 유용하다.
late final String name; 으로 먼저 선언 한 후, api 데이터를 받은 후 해당 name값에 받아온 data 값을 할당하는 식으로 하면 될 듯 하다.
6. const
컴파일 할 때 이미 고정된 상수 값이어야 한다. api data 값 같은게 들어가면 안된다. 앱스토어에 올리기 전에 이미 알고 있는 값을 다룰 때 쓰인다.
const api_key = "1232132131" 이런식
(자바스크립트의 const는 dart의 final이랑 비슷하다고 보면 된다.)
DATA TYPES
1. list
기본적으로 js의 배열과 같은 기능을 한다. 여기에 collection if 라는 신기능이 있다. 아래와 같이 배열의 마지막에 if 문을 추가해서 값을 넣을 수 있다. 이게 콜렉션 이프.
2. String Interpolation
js의 ${변수값} 이랑 똑같은 기능을 한다. 대신에, 대신에 해당 변수값에 변동이 없을시에는 {}를 생략해도 된다.
3. collection for
collection if와 같이 배열 값에 무언가를 추가해줄 수 있는데, 이때 js의 map함수와 같은 기능을 사용 할 수 있다.
4. map
js의 object와 같은 기능이다.
5. set
list와 유사하지만, 해당 set값의 각 각의 값은 유니크 하다. 아래 같은 경우는 1,2,3,4의 값이 이미 있기 때문에 해당 set값에 1,2,3,4 어느 값도 더 추가할 수가 없다. (5는 추가 가능)
6. optional positional parameters
position parameter에서 null 값이 들어갔을 때 디폴트 값을 지정하는 방법은 아래와 같다. (자주 사용 하지 않는 다고함)
FUNCTIONS
1. defining a funtion
Dart는 진정한 객체 지향 언어이므로 함수도 객체이며 타입이 Function입니다. 이는 함수를 변수에 할당하거나 다른 함수에 인수로 전달할 수 있음을 의미합니다.
```
// 하나의 표현식만 포함하는 함수의 경우 아래와 같이 단축 구문을 사용할 수 있습니다.
String sayHello(String name) => "Hello ${name} nice to meet you.";
num plus(num a, num b) => a + b;
void main() {
print(sayHello("sugar"));
}
```
2. named parameters
Named parameters는 명시적으로 required로 표시되지 않는 한 선택 사항입니다. 기본값을 제공하지 않거나 Named parameters를 필수로 표시하지 않으면 해당 유형은 기본값이 null이 되므로 null을 허용해야 합니다.
```
String sayHello(
{required String name, required int age, required String country}) {
return "${name} / ${age} / ${country}";
}
void main() {
print(sayHello(name: "sugar", age: 10, country: "Korea"));
}
```
3. optional positional parameters
Dart에서 [] 은 optional, positional parameter를 명시할 때 사용된다.
name, age는 필수값이고 []를 통해 country를 optional값으로 지정해줄 수 있다.
```
String sayHello(String name, int age, [String? country = ""]) {
return 'Hello ${name}, You are ${age} from the ${country}';
}
void main() {
var result = sayHello("sugar", 10);
print(result);
}
```
4. QQ Operator
js의 삼항 연산자 기능과 똑같은 기능이 있다. a? b : c --> a가 true면 b고 false면 c다.
?? 연산자를 이용하면 왼쪽 값이 null인지 체크해서 null이 아니면 왼쪽 값을 리턴하고 null이면 오른쪽 값을 리턴한다.
(이것도 js와 동일)
```
String capitalizeName(String? name) {
return name?.toUpperCase() ?? "";
}
```
??= 연산자를 이용하면 변수 안에 값이 null일 때를 체크해서 값을 할당해줄 수 있다.
```
void main() {
String? name;
name ??= "sugar";
name = null;
name ??= "js";
print(name); // js
}
```
5. typedef
자료형에 사용자가 원하는 alias를 붙일 수 있게 해준다. (자료형 이름의 별명을 만들 때 사용)
```
typedef ListOfInts = List<int>;
ListOfInts reverseListOfNumbers(ListOfInts list) {
var reversedList = list.reversed.toList();
return reversedList;
}
```
CLASSES
1. class 기본
class 에서 property에서는 반드시 변수명 앞에 type을 명시해주어야 한다. (함수 내에서는 var써도됨)
그리고 class내 method에서 property를 호출 할때는 this.name과 같이 this를 안써줘도 된다.
2. constructors
아래와 같이 생성자를 만들어줘도 되는데, 너무 번거롭고 길어지기 때문에 그 다음 코드대로 요약해서 진행한다.
(생성자명은 class명과 동일하게 해야함)
3. named constructor parameters
함수 named와 같이 class에서도 똑같이 사용 할 수 있다. 아래 코드 참조. (named로 습관 길들이는게 좋을듯 - 코드 깨끗)
4. named constructors
만약 생성자(constructor) 함수를 여러개 만들고 싶다면 어떨까?
Player.createBluePlayer({
required String name,
required int age,
}) : this.age = age,
this.name = name,
this.team = 'blue',
this.xp = 0;
```
콜론(:)을 사용하면 특별한 생성자 함수를 만들 수 있다.
콜론을 넣음으로써 dart에게 여기서 객체를 초기화하라고 명령할 수 있다.
✅ Named parameters
// 일반적인 방법
Player.createBlue({
required String name,
required int xp
}) : this.name = name,
this.xp = xp,
this.team = 'blue';
// 간소화된 방법(dart는 간소화된 방법을 추천)
Player.createRed({
required this.name,
required this.xp,
this.team = 'red',
});
✅ positional parameters
// 일반적인 방법
Player.createRed(String name, int xp)
: this.name = name,
this.xp = xp,
this.team = 'red';
// 간소화된 방법
Player.createRed(
this.name,
this.xp,
[this.team = 'red']
);
5. cascade notation
앞에서 선언한 class를 동일하게 사용할 경우 아래와 같이 ; 를 없애고 .. .. 으로 연속해서 쓸 수 있다. (마지막에 ; 써야함)
이때 ..는 앞에서 선언한 class 변수명을 뜻한다.
6. enums
enum은 우리가 실수하지 않도록 도와주는 타입이다.
dart에서 enum type을 만드는 법은 다음과 같다
```dart
enum Team {
red,
blue,
}
class Player {
String name;
int age;
Team team;
Player({
required this.name,
required this.age,
required this.team,
});
}
void main(){
var jisoung = Player(name: "jisoung", age: 17, team: Team.red);
var sushi = jisoung
..name = "sushi"
..age = 12
..team = Team.blue;
```
7. abstract (추상) class
Human을 abstract로 추상화 class로 선언해놓고 다른 class에서 해당 Human class로 extend 할 수 있다. 이때 반드시 abstract되었던 메소드를 써야한다. 안쓰면 에러남.
8. inheritance(상속)
9. mixin
여러 class에서 쓰일 속성이나 메소드를 mixin을 통해서 미리 정의해놓을 수 있다. mixin에는 생성자가 있어서는 안된다.
아래와 같이 사용 가능.