Dart 문법
Variable
- var type
1. var name = `pizza'; // 주로 local variable에서 선언할 때 사용
2. String name = `pizza`; // 주로 global variable이나 class property로 선언할 때 사용
- dynamic type
: 여러가지 타입을 가질 수 있는 변수에 사용
ex) 컴파일 시에 해당 변수의 타입을 알수 없을때(json 타입의 변수를 받아올 때)
다양한 타입을 가질 수 있으므로 남발하지 않는게 좋음
- final
: 한번만 할당 할 수 있음
타입 대신 사용하거나 타입에 추가로 선언
ex)
final name;
final String name2;
name = 'myName';
name = 'myName2';
- const
: class 레벨에서 변수를 변경 불가능하도록 선언 (컴파일 시 선언 이후 변경 불가)
암묵적으로 final, 인스턴스 변수에선 사용 불가(final 키워드를 사용해야 함)
상수로 선언할 때 뿐 아니라 상수 값을 만드는 데도 사용 가능
var foo = const [];
final bar = const [];
- Nullable variable
: Dart는 기본적으로 null-safety (의도치 않게 null 변수에 접근해 에러를 발생시키는 것을 막음);
잠재적으로 런타임 시 널 접근에 대한 오류를 코드 작성시의 분석 오류로 전환
-> 한번 Non-nullabel로 선언되면 null을 할당 불가능, 컴파일 시 최적화가 가능
1. 기본적으로 Non-nullable
2. 완벽하게 안전
String? name = `myName`;
//언래핑
name ?? 'is null2' // coalescing
name ??= 'is null' // coalescing, assign
name?.length // 체이닝
name! // null 일경우 에러
- late
- 선언 후 초기화되는 null이 불가능한 변수를 선언합니다.
- 변수를 지연하여 초기화합니다. (class property의 경우, 클래스 인스턴스 생성시에 할당을 하지 않아도 됨 but, 접근하기 전에 한번은 초기화 되어야 함)
-> 초기화 시 많은 자원이 필요하지만 해당 변수를 사용하지 않을 수도 있을 때 메모리 효율성을 위해 선언하거나 클래스 인스턴스 생성이후에 초기화 하고 싶을 때 사용
late String description;
void main() {
description = 'Feijoada!';
print(description);
}
타입
- Number (int, double)
num x = 1;
num y = 2.4;
int i = 1;
double j = 4.3;
- String (String)
var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";
var s5 = '''
You can create
multi-line strings like this one.
''';
var s6 = """This is also a
multi-line string.""";
String s7 = 'simple String';
String s8 = "single String";
//String interpolation
s8 = 'is ${s1 + '!!'}';
- Boolean (bool)
var a = true;
var b = false;
bool c = true;
- Records ((value1, value2))
(num, Object) pair = (42, 'a');
var first = pair.$1; // Static type `num`, runtime type `int`.
var second = pair.$2; // Static type `Object`, runtime type `String`.
({String name, int age}) userInfo(Map<String, dynamic> json)
// ···
// Destructures using a record pattern with named fields:
final (:name, :age) = userInfo(json);
- Lists (List, also known as arrays)
var list = [1, 2, 3];
assert(list.length == 3);
assert(list[1] == 2);
- Sets (Set)
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
var elements = <String>{};
elements.add('fluorine');
elements.addAll(halogens);
assert(elements.length == 5);
- Maps (Map)
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};
서브스크립트로 접근, 값이 없다면 null
함수
파라미터는 선언 순서대로 값을 전달
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
// => 와 ; 사이에는 값으로 평가되는 표현식만 가능 (ex. if문 불가)
축약 표현
named parameters
- 파라미터 부분은 {}로 감싸기
- nullable 로 받아오기
void enableFlags({bool? bold, bool? hidden}) {...}
enableFlags(bold: true, hidden: false);
- default 값 선언
/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool bold = false, bool hidden = false}) {...}
// bold will be true; hidden will be false.
enableFlags(bold: true);
- required 키워드 사용
void enableFlags({required bool bold,required bool hidden}) {...}
enableFlags(bold: true, hidden: true);
class
constructor
const double xOrigin = 0;
const double yOrigin = 0;
class Point {
final double x;
final double y;
// Sets the x and y instance variables
// before the constructor body runs.
Point(this.x, this.y);
// Named constructor
Point.origin()
: x = xOrigin,
y = yOrigin;
}
var paint = Paint()
..color = Colors.black
..strokeCap = StrokeCap.round
..strokeWidth = 5.0;
//cascade 방식으로 인스턴스 접근 가능
factory constructor
singleton 처럼 하나의 인스턴스만 생성(인스턴스가 없을 때만 새롭게 생성)
- 하위 유형의 인스턴스를 반환 가능
- 캐시에서 기존에 생성된 인스턴스를 반환
- this로 접근 불가능
class Logger {
final String name;
bool mute = false;
// _cache is library-private, thanks to
// the _ in front of its name.
static final Map<String, Logger> _cache = <String, Logger>{};
factory Logger(String name) {
return _cache.putIfAbsent(name, () => Logger._internal(name));
}
factory Logger.fromJson(Map<String, Object> json) {
return Logger(json['name'].toString());
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
extends
class Television {
void turnOn() {
_illuminateDisplay();
_activateIrSensor();
}
// ···
}
class SmartTelevision extends Television {
void turnOn() {
super.turnOn();
_bootNetworkInterface();
_initializeMemory();
_upgradeApps();
}
// ···
}
abstract class
//extends를 이용해 상속, 확장을 할 수 있다, 클래스가 필수적으로 갖춰야할 청사진
abstract class Human {
void walk();
}
class Player extends Human {
void walk() {
print("working!");
}
}
mixin
: with로 참조하는 mixin의 프로퍼티들만 가져다 사용 가능
mixin runForestRun {
void run() {
print("RUN!!!!!!!!!!!!!!!!!!!");
}
}
enum
enum Vehicle implements Comparable<Vehicle> {
car(tires: 4, passengers: 5, carbonPerKilometer: 400),
bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);
const Vehicle({
required this.tires,
required this.passengers,
required this.carbonPerKilometer,
});
final int tires;
final int passengers;
final int carbonPerKilometer;
int get carbonFootprint => (carbonPerKilometer / passengers).round();
bool get isTwoWheeled => this == Vehicle.bicycle;
@override
int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}