반응형

Dart, 연산자(Operators)

 

글. 수알치 오상문 

 

다트는 다음 표에 나오는 연산자를 지원합니다.

(참조: 클래스 멤버 연산자 구현 operators as class members.)

 

  구분                                  연산자

단항 접미형 expr++    expr--    ()    []    .    ?.
단항 접두형 -expr    !expr    ~expr    ++expr    --expr      await expr   
곱셈, 나누기 나머지,  *    /    %  ~/
더하기, 빼기 +    -
쉬프트(밀기) <<    >>    >>>
비트 AND &
비트 XOR ^
비트 OR |
비교 및 형 검사 >=    >    <=    <    as    is    is!
상등 ==    !=   
논리 AND &&
논리l OR ||
왼쪽이 null 이면 오른쪽 선택 ??
조건 연산자 expr1 ? expr2 : expr3
종속 계단 표기(cascade) ..    ?..
대입(할당) =    *=    /=   +=   -=   &=   ^=   등등.

경고: 연산자 우선순위는 상세 규격을 참조하세요. Dart language specification.

 

연산자를 이용하여 다음처럼 다양한 수식을 만들 수 있습니다.

 

a++

a + b

a = b

a == b

c ? a : b

a is T

 

연산자 표에서 윗 줄에 있는 연산자들의 우선 순위가 높습니다(특수한 경우는 제외). 나머지 연산자(%)는 논리 AND 연산자(&&)보다 우선 순위가 더 높습니다. 연산자 우선 순위 때문에 다음 두 코드는 동일하게 실행됩니다.

 

// 괄호는 읽기 좋게 해줍니다.  

if ((n % i == 0) && (d % i == 0))

    ...

 

// 읽기 어렵지만, 위 문장과 같습니다.

if (n % i == 0 && d % i == 0)

    ...

 

경고: 두 개의 피연산자를 사용하는 연산자의 경우, 가장 왼쪽 피연산자가 사용 방법을 결정합니다. 예를 들어, Vector와 Point 객체가 있는 경우 aVector + aPoint는 Vector 더하기(+)를 사용합니다.

 

산술 연산자

+ 더하기
빼기
-수식 음수
* 곱하기
/ 나누기 (실수 결과)
~/ 나누기 (정수 결과)
% 나머지

예:

assert(2 + 3 == 5);

assert(2 - 3 == -1);

assert(2 * 3 == 6);

assert(5 / 2 == 2.5); // 결과는 double

assert(5 ~/ 2 == 2); // 결과는 int

assert(5 % 2 == 1); // 나머지

assert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');

 

선위/후위형 증가/감소 연산자  

++변수 변수 값을 1 증가한다.  (수식에 사용되면 먼저 변수를 1 증가하고 수식에 사용됨)
변수++ 변수 값을 1 증가한다.  (수식에 사용되면 먼저 수식에 사용하고 변수를 1 증가함)
--변수 변수 값을 1 감소한다.  (수식에 사용되면 먼저 변수를 1 감소하고 수식에 사용됨)
변수-- 변수 값을 1 감소한다.  (수식에 사용되면 먼저 수식에 사용하고 변수를 1 감소함)

예:

var a, b;

a = 0;

b = ++a; // 1 증가한 후에 수식에 사용

assert(a == b); // 1 == 1

a = 0;

b = a++; // b에 a를 사용한 후에 a를 1 증가함

assert(a != b); // 1 != 0

a = 0;

b = --a; // 1 감소한 후에 수식에 사용

assert(a == b); // -1 == -1

a = 0;

b = a--; // b에 a를 사용한 후에 a를 1 감소함

assert(a != b); // -1 != 0

 

상등/비교 연산자

== 같으면 true
!= 다르면 true
> 왼쪽이 더 크면 true
< 왼쪽이 더 작으면 true
>= 왼쪽이 크거나 같으면 true
<= 왼쪽이 작거나 같으면 true

두 객체 x, y가 같은 것을 표현하는지 비교하려면 == 연산자를 사용합니다. (만약 두 객체가 같은 객체인지 비교하려면  identical() 함수를 사용합니다.)

 

== 연산자는 다음처럼 동작합니다.

  1. x 또는 y가 모두 null이면 true를 돌려주고 하나만 null이면 false를 돌려줍니다.
  2. 메서드 호출(x. == (y))의 결과를 반환합니다. (== 연산자는 왼쪽 객체의 비교 기능을 호출합니다.)

예:

assert(2 == 2);

assert(2 != 3);

assert(3 > 2);

assert(2 < 3);

assert(3 >= 3);

assert(2 <= 3);

 

자료 형 검사 연산자 

as 형변환(Typecast),  (라이브러리 접두어 지정에도 사용 library prefixes )
is 객체가 지정한 형과 같으면 true 
is! 객체가 지정한 형과 다르면 true 

객체 obj를 구현할 때 T를 인터페이스했다면  obj is T 결과는 true입니다. 그러므로 obj is Object 결과는 항상 true입니다.

 

예: // 형변환이 확실한 경우 

(employee as Person).firstName = 'Bob';

 

만약 형변환 T가 확실하지 않으면 먼저 검사한 후에 처리합니다.

 

if (employee is Person) {   // 형 검사

   employee.firstName = 'Bob';

}

 

참고: 위 예제 코드가 완전히 동일하진 않습니다. employee가 null이거나 Person이 아니면 첫 번째 예제는 예외가 발생합니다.

 

할당/대입 연산자

= 연산자를 사용하여 값을 할당 할 수 있습니다. 할당 대상 변수가 null 인 경우에만 할당하려면 ??= 연산자를 사용합니다.

 

// a에 value 할당

a = value;

// b가 null인 경우에만 할당

b ??= value;

 

복합 대입 연산자는 다음과 같습니다. 

= –= /= %= >>= ^=
+= *= ~/= <<= &= |=

복합 대인 연산자 동작은 다음처럼 이후어집니다.

연산자 op인 경우 a op= b a = a op b
예: a += b a = a + b

 

var a = 2;  

a *= 3;   // a = a * 3

assert(a == 6);

 

논리 연산자

!수식 수식의 논리값을 반대로 바꿉니다. true이면 false, false이면 true
|| 논리 OR  (어느 한쪽이라도 true이면 true)
&& 논리 AND (양쪽이 true일 때만 true)

 

if (!done && (col == 0 || col == 3)) {

    // ... 

}

 

비트 연산자

일반적으로 정수형 변수/값을 대상으로 비트 단위로 논리 연산을 하거나 밀어내기 연산을 합니다. 

& AND (양쪽 비트가 1이면 결과는 1)
| OR (한쪽 비트라도 1이면 결과는 1)
^ XOR (양쪽 비트가 같으면 0, 아니면 1)
~수식 모든 비트를 대상으로 1이면 0, 0이면 1로 바꿈 
<< 왼쪽으로 비트를 밀어냄
>> 오른쪽으로 비트를 밀어냄

 

final value = 0x22;

final bitmask = 0x0f;

assert((value & bitmask) == 0x02); // AND

assert((value & ~bitmask) == 0x20); // AND NOT

assert((value | bitmask) == 0x2f); // OR

assert((value ^ bitmask) == 0x2d); // XOR

assert((value << 4) == 0x220); // Shift left

assert((value >> 4) == 0x02); // Shift right

 

조건 연산자

조건 연산자는 if else 조건문의 단축형 연산자이며 다음 형식을 사용합니다.

 

조건식 ? 수식1 :수식2

 

조건식이 참이면 수식1이 선택되고 아니면 수식2가 선택되어 사용됩니다.

 

var visibility = isPublic ? 'public' : 'private';

 

유사한 연산자로는 ?? 연산자가 있습니다.

 

수식1 ?? 수식2

 

만약 수식1이 null이 아니면 수식1이 선택되고, null이면 수식2가 선택됩니다.

 

String playerName(String? name) => name ?? 'Guest';  // name이 null이면 'Guset' 선택

 

위 예제는 다른 방식으로 작성할 수 있지만 간결하진 않습니다. 

 

// ?: 연산자 사용.

String playerName(String? name) => name != null ? name : 'Guest';

 

// 고전적인 if-else 문장 사용

String playerName(String? name) { if (name != null) { return name; } else { return 'Guest'; } }

 

종속 계단 표기(Cascade) 연산자

종속 계단 표기 연산자를(.. 그리고 ?..) 이용하면 동일한 객체에 대한 표기 작업을 간결하게 할 수 있습니다. 함수 호출 외에도 동일한 객체의 필드에 접근할 수 있습니다. 때로는 임시 변수 생성을 줄이고 효율적인 코드를 작성할 수 있습니다.

(참고: 엄격하게 구분하면 .. 표기는 연산자가 아니라 다트 문법입니다.)

 

다음 코드를 살펴보면,

 

var paint = Paint()

    ..color = Colors.black

    ..strokeCap = StrokeCap.round

    ..strokeWidth = 5.0;

 

생성자 Paint ()는 Paint 객체를 반환합니다. 종속형 계단 표기법을 따르는 코드는 반환될 수있는 모든 값을 무시하고 이 객체에 작동합니다. 

 

앞 예제는 다음 코드와 같습니다. 

var paint = Paint();

paint.color = Colors.black;

paint.strokeCap = StrokeCap.round;

paint.strokeWidth = 5.0;

 

객체가 null 가능성이 있으면 null 제외 표기(?..)를 사용합니다. ?..로 시작하면 null 객체에 대해 작업을 하지 않습니다.

 

querySelector('#confirm') // 객체 얻기

    ?..text = 'Confirm'      // 그것의 멤버 사용, 단 null이면 작업 안함 

    ..classes.add('important')

    ..onClick.listen((e) => window.alert('Confirmed!'));

 

버전 참고:  ?.. 문법은 다트 2.12.부터 지원합니다. 이전 버전에서는 이렇게 사용합니다.

var button = querySelector('#confirm');

button?.text = 'Confirm';

button?.classes.add('important');

button?.onClick.listen((e) => window.alert('Confirmed!'));

 

또한 중첩된 계단 표기도 가능합니다.

 

final addressBook = (AddressBookBuilder()

    ..name = 'jenny'

    ..email = 'jenny@example.com'

    ..phone = (PhoneNumberBuilder()

        ..number = '415-555-0100'

        ..label = 'home')

      .build())

  .build();

 

그외 연산자

() 함수 함수 호출 표현 
[] 리스트 접근 리스트 인덱스를 이용한 접근
. 멤버 접근 객체의 멤버에 접근
?. 조건 멤버 접근 접근 대상이 null이 아닌 경우에 멤버에 접근

 ., ?., .. 연산자 참고: Classes.

 

<이상> 

 

반응형

'Dart' 카테고리의 다른 글

Dart, 디버깅 함수 assert()  (0) 2021.06.15
Dart, 흐름 제어 if, for, while, do while, switch  (0) 2021.06.15
Dart, 함수 비교 테스트  (0) 2021.06.15
Dart, 접근 범위와 클로저(closure)  (0) 2021.06.15
Dart, 이름없는 함수  (0) 2021.06.15

+ Recent posts