참고
노마드 코드의 무료 강의 Dart 시작하기를 들으면서 정리한 요약본입니다.
링크에서 강의를 들을 수 있으며, 저작권 상 문제가 있다면 댓글로 알려주시면 조치하겠습니다.
Dart
Why Dart?
- UI 에 최적화된 언어
- 빠름
- 두가지 컴파일러
- Dart Native ( 여러 cpu 의 아키텍처에 맞게 변환 = iOs, Android, Windows, Linux, Mac … )
- 거의 모든 곳에서 동작하도록 컴파일 가능
- just in time(JIT, 코드의 결과를 바로 화면으로 볼 수 있음. 가상 머신에서 동작하는 거여서 조금 느릴 수 있음. ) > 개발 도중에만 쓰임
- 빠른 피드백이 가능함
- ahead of time (AOT, 컴파일 먼저 > 그 결과인 바이너리 배포 ) > 배포할 때 쓰임
- 하지만 최종 결과물은 컴파일이 되서 빠름
- Dart Web ( dart > javascript)
- Dart Native ( 여러 cpu 의 아키텍처에 맞게 변환 = iOs, Android, Windows, Linux, Mac … )
- null safety
- 대부분의 프로그래밍 언어에서 null 참조하면 crash 나지만… dart 에서는 걱정하지 않아도 됨
How To Learn?
link: dartpad.dev
Variables
Var keyword
void main() {
var hello = '안녕';
// name = 1; - 업데이트 할 때에는 기존 type 과 일치해야 함
String world = '세상';
}
- 관습적으로 함수나 메소드 내부에 로컬 변수를 선언할 때에는 var 사용
- class에 변수 또는 property 의 경우 타입 지정
- 어떤 경우든 변수는 업데이트 가능함
dynamic type
var name; // dynamic type
name = 'nini';
name = 17;
name = true;
dynamic name;
if (name is String) { // name is string }
if (name is int) { // name is int }
// name is dynamic
- 여러가지 타입을 가질 수 있는 변수에 쓰는 키워드
- 사용하는게 권장되지는 않지만 유용함
- 따라서 꼭 필요할 때만 써야함
- dynamic 변수로 작업하고 있다면 타입을 먼저 확인해야 함
nullable variables
- 개발자가 null 값을 참조할 수 없도록 함
- null 을 참고하면 런타임 에러가 발생하게 됨
// without null safety
bool isEmpty(String string) => string.length == 0;
main() { isEmpty(null); } // 사용자 기기에서 에러 발생 = 컴파일러가 잡지 못함
- 어떤 데이터 또는 변수가 null 이 될 수 있는지 명시하는 것이 nullable variable
- 기본적으로는 모든 변수가 non-null
String nico = 'nico';
nico = null; // not possible
String? nico = 'nico';
nico = null; // possible
if (nico != null) { // nullable variable 일 경우 null 이 아닌지 확인해야 함 }
nico?.isNotEmpty; // 단축문법도 사용 가능
final variables
// 나중에 수정 가능한 변수가 만들어짐
var name;
String name;
// 추후 수정할 수 없게 만드려면 ( js, ts 의 const )
final name = 'x';
final String name = 'y'; // type 지정도 가능
late variables
late final x;
// do something, go to api
print(x); // 할당 전에는 접근 불가 에러 발생
x = 'x';
print(x); // 할당 되어 접근 가능
late var y;
초기 데이터 없이 변수를 만들 수 있게 해줌
또한 final 에 쓰는 경우 최초 한번만 할당 할 수 있음
data fetching 을 할 때 유용함
constant variables
const api = 1233333; // (o) 바뀌지 않고 컴파일 될 때 이 값을 알 고 있어야 함.
const api = fetchApi(); // (x) compile time constant 가 아님. api 에서 가져와야 하는 거여서 const 가 아닌 final 이 맞음. 앱스토어에 앱을 올리기 전에 알고 있는 값이어야 함.
const max_allowed_price = 120; // compile time 에 평가되게 됨. = 앱에 담긴 코드를 앱스토어로 보내기 전에 평가 됨
- js/ts 의 const 의 다름 ( 이건 오히려 final 과 비슷함 )
- dart 의 const 는 compile time constant 를 만들어줌
- final 과 똑같이 수정이 안됨. 즉 상수임.
- 하지만 더 중요한건 compile-time 에는 알고 있는 값이어야 함.
Data Types
basic data types
// 타입도 Object로 이루어져 있음
String a;
bool b;
int c;
double d;
num e; // integer or double. parent of integer and double.
lists
var numbers = [];
List numbers = [1, 2,];
// supports collection if/for
var giveMeFive = ture;
var numbers = [
if (giveMeFive) 5, // collection if
]
string interpolation
var name = 'yeye';
// variable already exists $aa
// not exists like operation ${bb + 32}
var age = 10;
var greeting = "hello, my name is $name, and I'm ${age +3}";
- use quote or double quote
- use variable after $
collection for
var oldFriends = ['a', 'b'];
var newFriends = [
'c',
'd',
for (var friend in oldFriends) "love $friend"
]
maps
var player = { // Map<string, object=""> player
'name': 'me",
'level': 99,
'power': true,
}
Map<int, bool=""> player = {};
Map<list, bool> player = {};
- Dart 에서는 모든 것이 Object ( Typescript 의 any 라고 보면 됨 )
sets
- elements in the set are unique
- dart set - js set, python set
- dart list - js array, python list
Functions
defining a function
void say(String name){
print("Hello $name nice to meet you!");
}
String say(String name){
return "Hello $name nice to meet you!";
}
// arrow syntax
String say(String name) => "Hello $name nice to meet you!";
named parameters
// null safety - use default value or required
String say({String name = '', int age = 99, required String country}){
return "Hello $name, your age is $age, and you come from $country";
}
say(name:'name', age:19, country:'south korea');
- positional parameter vs named parameter
optional positional parameters
String say(String name, int age, [String? country = 'south korea']) => 'Hello $name, you are $age, and from $country';
say('yeye', 12);
- [type? variableName = defaultValue]
QQ(Question Question) operator
- ?? : left ?? right > left 가 null 이면 return right
- ??=
String captalize(String? name) => name?.toUpperCase() ?? 'null';
capitalize(null);
String? name;
name ??= 'nico';
typedef
List reverseListOfNumbers(List list) {
var reversed = list.reversed; // iterable
return reversed.toList();
}
// =>
typedef ListOfIntegers = List;
ListOfIntegers reverseListOfNumbers(ListOfIntegers list) {
var reversed = list.reversed; // iterable
return reversed.toList();
}
- alias of something tiny
Classes
first dart class
class Player {
String name = 'hehe';
int xp = 1500;
void say() {
print('hi i am $name'); // variable 이름이 중복되지 않는 이상 this 를 쓸 필요 없음.
}
}
void main() {
var player = Player(); // new Player () not required
print(player.name);
print(player.name);
player.say();
}
constructors
class Player {
// version 1
late String name;
late int xp;
Player(String name, int xp) {
this.name = name;
this.xp = xp;
}
// version 2 : 깔끔하고 중복 코드가 없음
String name;
int xp;
Player(this.name, this.xp);
void say() {
print('hi i am $name'); // variable 이름이 중복되지 않는 이상 this 를 쓸 필요 없음.
}
}
void main() {
var player = Player('hehe', 999); // new Player () not required
print(player.name);
player.say();
}
named constructor parameters
class Player {
String name;
int xp;
String team;
int age;
Player(
{required this.name, required this.xp, required this.team, this.age = 3});
void say() {
print('hi i am $name');
}
}
void main() {
var player = Player(name: 'hehe', xp: 999, team: 'blue', age: 1);
print(player.name);
player.say();
}
named constructors
class Player {
String name, team;
int xp, age;
// constructor ( 생성자 )
Player(
{required this.name,
required this.xp,
required this.team,
required this.age});
// named constructor
Player.test1(
{required this.name,
required this.xp,
this.team = 'hello',
this.age = 4});
// use : initiallize Player here
Player.test2({required name})
: this.name = name,
this.xp = 3,
this.team = 'team',
this.age = 5;
void say() {
print('hi i am $name');
}
}
void main() {
var player = Player(
name: 'hehe',
xp: 999,
team: 'blue',
age: 1,
);
print(player.name);
var newPlayer = Player.test1(name: 'name', xp: 5);
print(newPlayer.name);
}
cascade notation
void main() {
var player = Player(
name: 'hehe',
xp: 999,
team: 'blue',
age: 1,
)
..name = 'las'
..xp = 1
..team = 'aa'
..age = 3;
}
enums
enum Team { read, blue }
//
Team team;
// ...
..team = Team.blue;
abstract classes
// 일종의 청사진
abstract class Human {
void walk();
}
class Player extends Human {
@override
void walk() {
// TODO: implement walk
}
}
void main() {}
inheritance
class Human {
final String name;
Human(this.name);
void say() {
print('hi $name');
}
}
enum Team { red, blue }
class Player extends Human {
final Team team;
// super enable child can communicate with parents
// Player(super.name, this.team);
Player({required this.team, required String name}) : super(name);
}
void main() {
var player = Player(team: Team.blue, name: 'name');
}
mixins
- 생성자가 없는 클래스
- 클래스에 프로퍼티를 추가하거나 할 때 사용함
```dart
class Strong {
final double strength = 1500.99;
}
class QuickRunner {
void runQuick() {
print('run run run!');
}
}
class Player with Strong, QuickRunner {
final String team;
Player(this.team);
}
void main() {
var player = Player('team');
player.runQuick();
print(player.strength);
}
```</list</int,></string,>