Dart는 interpolation은 $
을 이용한다.
예제
stringfy(2, 3) 함수는 '2 3'을 리턴한다.
String stringify(int x, int y) {
return '$x $y';
}
null일 수 있는 변수는 ?
를 통해 선언한다.
예제
String? name = 'Jane';
String? address = null;
null을 다루는 두가지 연산자가 있다.
??=
: 왼쪽 변수의 값이 null이라면, 오른쪽 값을 할당한다??
: 왼쪽 값이 null이라면 오른쪽 값을 출력하고, null이 아니라면 그대로 출력한다.예제
String? foo = 'a string';
String? bar; // = null
// Substitute an operator that makes 'a string' be assigned to baz.
String? baz = foo ?? bar;
void updateSomeVars() {
// Substitute an operator that makes 'a string' be assigned to bar.
bar ??= 'a string';
}
null일지 모르는 프로퍼티에 대한 접근을 안전하게 하기 위해서, dot(.)앞에 ?
를 이용한다.
예제
myObject?.someProperty
// 위 아래가 같은 표현
(myObject != null) ? myObject.someProperty : null
final aListOfStrings = ['one', 'two', 'three'];
final aSetOfStrings = {'one', 'two', 'three'};
final aMapOfStringsToInts = {
'one': 1,
'two': 2,
'three': 3,
};
같은 객체에 대한 연속적인 연사자를 사용하기 위해 사용한다.
myObject.someMethod();
myObject..someMethode();
// 같은 표현이다.
// 하지만 리턴값은 someMethode() 의 리턴값이 아닌 myObject의 reference다.
예제
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
querySelector('#confirm')
..text = 'Confirm'
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
두 코드는 같다.
class MyClass {
final List<int> _values = [];
void addValue(int value) {
_values.add(value);
}
// A computed property.
int get count {
return _values.length;
}
}
다트의 두가지 함수의 파라미터 종류
일반적인 positional 방법
int sumUp(int a, int b, int c) {
return a + b + c;
}
// ···
int total = sumUp(1, 2, 3);
이 positional 파라미터들을 optional하게 표현할 수 있다.
int sumUpToFive(int a, [int? b, int? c, int? d, int? e]) {
int sum = a;
if (b != null) sum += b;
if (c != null) sum += c;
if (d != null) sum += d;
if (e != null) sum += e;
return sum;
}
int total = sumUpToFive(1, 2);
int otherTotal = sumUpToFive(1, 2, 3, 4, 5);
optional 파라미터들은 설정을 따로 하지 않는다면, 기본적으로 null이다.
그리고 optional 파라미터의 기본값 설정은 다음과 같이 한다.
int sumUpToFive(int a, [int b = 2, int c = 3, int d = 4, int e = 5]) {
// ···
}
// ···
int newTotal = sumUpToFive(1);
print(newTotal); // <-- prints 15
중괄호를 사용하면 파라미터를 optional하게 파라미터 name으로 받을 수 있다.
void printName(String firstName, String lastName, {String? suffix}) {
print("$firstName $lastName ${suffix ?? ''}");
}
printName('Avinash', 'Gupta');
printName('Poshmeister', 'Moneybuckets', suffix: 'IV');
optional named parameter의 기본값은 따로 설정하지 않는다면 null이다.
만약 parameter의 타입을 non-nullable하게 하고 싶다면, required로 선언하거나 기본값을 설정해주면 된다.
void printName(String firstName, String lastName, {String suffix = ''}) {
print('$firstName $lastName $suffix');
}
함수는 optional positional 과 optional named를 동시에 가질 수 없다.
예제: copyWith()메소드 구현, 파라미터로 넘어온 데이터가 non-null이라면 복사하여 새로운 객체를 반환
class MyDataObject {
final int anInt;
final String aString;
final double aDouble;
MyDataObject({
this.anInt = 1,
this.aString = 'Old!',
this.aDouble = 2.0,
});
// Add your copyWith method here:
MyDataObject copyWith({int? newInt, String? newString, double? newDouble}){
return new MyDataObject(anInt: newInt ?? this.anInt, aString: newString ?? this.aString, aDouble: newDouble ?? this.aDouble);
}
}
Dart의 예외는 checked되지 않은 예외다. null이 아닌 모든 예외를 throw할 수 있고, catch할 수 있다.
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e');
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}
on : 특정 예외에 대한 처리를 할 때 사용
catch: 모든 예외를 처리할 때 사용
rethrow : 완전히 예외를 처리하지 못할 때, 사용
finally: 예외를 처리했던 안했던간에 반드시 실행되는 부분 (보통 clean up 용도로 사용
constructor에서 값을 할당할 때 쉽게 할당하는 방법
this.propertyName 사용
class MyColor {
int red;
int green;
int blue;
MyColor(this.red, this.green, this.blue);
}
final color = MyColor(80, 80, 128);
Named Parameters 로도 가능
class MyColor {
...
MyColor({required this.red, required this.green, required this.blue});
}
final color = MyColor(red: 80, green: 80, blue: 80);
default 값 설정방법
MyColor([this.red = 0, this.green = 0, this.blue = 0]);
// or
MyColor({this.red = 0, this.green = 0, this.blue = 0});
contstructor를 구현할 때, contstructor body가 실행되기 전에 어떤 것을 설정해야할 경우가 있다.
final 필드 변수들이 반드시 constructor 실행전에 값을 가지고 있어야할 경우, initializer lists를 사용한다.
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson(): ($x, $y)');
}
그리고 개발과정 assert를 다룰때도 사용한다.
NonNegativePoint(this.x, this.y)
: assert(x >= 0),
assert(y >= 0) {
print('I just made a NonNegativePoint: ($x, $y)');
}
class 들의 다양한 contructors를 가지도록 하기 위해 Named constructors를 제공한다.
class Point {
double x, y;
Point(this.x, this.y);
Point.origin()
: x = 0,
y = 0;
}
factory constructor를 지원한다.
class Square extends Shape {}
class Circle extends Shape {}
class Shape {
Shape();
factory Shape.fromTypeName(String typeName) {
if (typeName == 'square') return Square();
if (typeName == 'circle') return Circle();
print('I don\'t recognize $typeName');
throw Error();
}
}
특정 조건에 대해서 다른 constructor로 redirect할 수 있다.
class Automobile {
String make;
String model;
int mpg;
// The main constructor for this class.
Automobile(this.make, this.model, this.mpg);
// Delegates to the main constructor.
Automobile.hybrid(String make, String model) : this(make, model, 60);
// Delegates to a named constructor
Automobile.fancyHybrid() : this.hybrid('Futurecar', 'Mark 2');
}
어떠한 클래스로 절대 변하지 않을 객체를 생성한다면, 컴파일 타임에 constants로 선언하자. const
생성자를 선언하고, 모든 인스턴스 필드를 final로 선언하자.
class ImmutablePoint {
const ImmutablePoint(this.x, this.y);
final int x;
final int y;
static const ImmutablePoint origin = ImmutablePoint(0,0);
}
출처 : Dart-공식문서