이번에도 알고리즘을 푸는데 처음 보는 연산자가 있었다.
그래서 오늘은 처옴 보는 연산자인 Cascade 연산자, `..`에 대해 파헤쳐본다.
Cascade 연산자
객체를 한 번만 호출하고 여러 개의 메서드나 속성을 연속적으로 호출할 수 있게 해주는 연산자.
즉, 객체를 여러 번 참조하지 않고 한 줄로 여러 작업을 수행할 수 있도록 도와주는 문법이다.
`..`는 메서드나 속성을 호출하고 있는 객체를 반환한다.
사용법
Cascade 연산자를 사용하지 않는 코드
class Person {
String name = '';
int age = 0;
void setName(String name) {
this.name = name;
}
void setAge(int age) {
this.age = age;
}
void introduce() {
print('My name is $name and I am $age years old.');
}
}
void main() {
var person = Person();
person.setName('Alice');
person.setAge(25);
person.introduce();
}
- `person`객체를 반복적으로 참조해서 코드가 길어지고 가독성이 떨어진다.
Cascade 연산자를 사용한 코드
void main() {
var person1 = Person()
..setName('Alice')
..setAge(25)
..introduce();
var person2 = Person()
..name = 'Alice'
..age = 25
..introduce();
}
- `person`을 한 번만 선언하고 여러 개의 메서드를 체이닝 방식으로 호출할 수 있다.
- `..`에 의해 메서드나 속성을 호출한 객체를 다시 반환한다.
메서드의 타입이 다른 경우
class Person {
void sayHello() {
print('Call sayHello');
}
int sayName() {
print('Call sayName');
return 1;
}
String sayAge() {
print('Call sayAge');
return '';
}
}
void main() {
var person = Person()..sayHello()..sayName();
}
- `sayHello`, `sayName`, `sayAge`는 반환 타입이 다르지만 `..`연산자로 인해 사용이 가능하다.
- 다른 포스트에는 사용이 안된다고 나와있던데 지금은 왠지 모르지만 잘 동작한다.
심화
아래의 코드가 안되는 이유
var person = Person().sayHello().sayName();
- `Person().sayHello()`를 호출하면 반환 값이 없으므로 `void.sayName()`가 되어 호출이 불가능하다
- 그래서 `sayName()`을 호출하기 위해서는 `person`객체가 있어야 하므로 `..`연산자를 `sayHello()`에 사용한다.
- 그럼 `Person()..sayHello().sayName()`이 되고 마치 `Person()..sayHello() == var person`으로 생각할 수 있다.
- 그럼 결국엔 `person.sayName()`이라고 생각할 수 있는데 여전히 에러는 발생한다.
- 이유는 아직 `var person`에 인스턴스(객체)가 할당되지 않은 상태이기 때문이다. 모든 체이닝이 다 끝이 나야 할당이 된다.
- 즉, `Person()..sayHello() == var person`가 성립되지 않으므로 `person.sayName()`이라고 생각했던 것도 성립이 되지 않기 때문에 에러가 발생하고 있는 것이다.
- 그래서 `sayName()`에서 인스턴스를 반환해야 `var person`에 제대로 할당이 되므로, 반환하기 위해 `..`연산자를 사용한다.
- 최종적으로 `Person()..sayHello()..sayName();`은 정상 동작하여 `var person`에 인스턴스를 할당한다.
주의할 점
생성자에서 바로 사용하는 경우
class Car {
String model;
Car(this.model);
void show() {
print('Car model: $model');
}
}
void main() {
var car = Car('Tesla')..show()..model = 'BMW'; // ✅ 정상 작동
Car('Audi')..model = 'Benz'; // ❌ 에러 발생!
}
- `Car('Audi')..model = 'Benz';` 는 객체를 변수에 저장하지 않고 곧바로 cascade 연산자를 사용하므로 에러가 발생한다.
- 생성자 (Car()) 호출 결과가 더 이상 사용되지 않으므로 객체가 메모리에서 제거될 수 있다.
객체가 null일 경우
Person? person;
person?..setName('Bob')..setAge(30); // person이 null이면 아무것도 실행되지 않음
- `person`이 `null`이면 에러가 발생하지만 `?..`을 사용하여 실행을 막아 에러를 방지한다.
정리
- `..`연산자는 메서드를 호출한 객체를 반환한다.
- 메서드의 반환 타입이 없거나 다르더라도 `..`를 사용하면 메서드를 호출한 객체를 반환한다.
'TIL(Today I Learned)' 카테고리의 다른 글
[TIL-011] List<String> → List<int> 타입 변환 오류 해결 방법 (0) | 2025.03.17 |
---|---|
[TIL-010] Dart 실전 문법 파헤치기 - Future Class (1) | 2025.03.14 |
[TIL-008] Dart 실전 문법 파헤치기 - 타입 변환 메서드 (0) | 2025.03.12 |
[TIL-007] Dart로 콘솔 쇼핑몰 만들기-2 (0) | 2025.03.11 |
[TIL-006] Dart로 콘솔 쇼핑몰 만들기-1 (0) | 2025.03.10 |