https://dart.dev/guides/language/language-tour
위 문서로 공부하며 기억해둘만한 내용만 정리
실습 사이트
부가적인 내용이나 다른 코드가 섞여있을 수 있습니다.
- main은 앱이 실행되는 최상단 함수
- 문자열 리터럴 안에 변수나 표현식 가능
void main() {
var intVal = 123;
String strVal = '456';
print('intVal = ${intVal}, strVal = ${strVal}');
}
- 변수에는 객체가 들어가고, 모든 객체는 클래스의 인스턴스
- 모든 객체는 Object를 상속
- 다트는 강타입 언어
void main() {
var test = 123;
test = 456;
test = '123';
}
Error: A value of type 'String' can't be assigned to a variable of type 'int'.
test = '123';
var를 이용하면 타입이 유추될 수 있지만, 한번 선언된 타입은 바뀌지 않는다.
- null safety를 활성화시키면 변수는 null을 포함할 수 없음
void main() {
int val = null; // var val = null; 가능
print(val);
}
Error: The value 'null' can't be assigned to a variable of type 'int' because 'int' is not nullable.
int val = null;
- ?를 붙이면 nullable하다.
void main() {
int? val = null;
print(val); // null
}
int이거나 null일 수 있다.
출력 값은 null
- !를 이용하여 null이 아님을 단언할 수 있다.
void main() {
int? nullableValue = null;
print(nullableValue);
int val = nullableValue!;
}
null
Uncaught TypeError: Cannot read properties of null (reading 'toString')Error: TypeError: Cannot read properties of null (reading 'toString')
런타임에 예외가 난다.
void main() {
int? nullableValue = null;
print(nullableValue);
int val = nullableValue;
}
Error compiling to JavaScript:
Info: Compiling with sound null safety
lib/main.dart:4:13:
Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
int val = nullableValue;
^
Error: Compilation failed.
null safety 변수에는 nullable 변수를 넣을 수 없다. !를 활용해야 가능
명시적으로 모든 타입 허용하고 싶다면, Object?
- Generic 지원
void main() {
List<int> intList = [1, 2, 3];
for(int i=0; i<intList.length; i++) {
print(intList[i]);
}
}
- 함수를 지원
void foo() {
void bar() {
print('bar');
}
print('foo');
bar();
}
void main() {
var func = foo;
func();
}
변수에 함수를 넣을 수도 있다.
함수 내에 중첩 함수를 작성할 수도 있다.
클래스 또는 객체에 연결된 스태틱 및 인스턴스 메소드도 지원.
- 최상위 변수, 클래스 내에 스태틱 및 인스턴스 변수도 지원
var test = 1;
class MyClass {
static int test = 2;
int innerTest = 3;
}
void main() {
print(test);
print(MyClass.test);
print(new MyClass().innerTest);
}
문법을 알고 작성한 것은 아니고, 그냥 임의로 작성해봤는데 컴파일이 된다.
- 접근제어자가 없다.
자바의 public, private, protected 등의 키워드가 없다. 변수나 메소드 앞에 _를 붙여야한다.
- 런타임 표현식과 명령문을 모두 가질 수 있다.
void main() {
var num = 1;
var result = num > 0 ? 'positive' : 'not positive';
print(result);
}
위와 같은 삼항연산자 가능
- warnings와 errors 두 종류의 문제를 리포트해준다.
warnings는 프로그램 실행을 막지는 않음
errors는 런타임 에러와 컴파일 타임 에러
- 키워드
https://dart.dev/guides/language/language-tour#keywords
예약어 살펴보기
- 변수는 참조를 저장
var name = 'Bob';
name은 값이 'Bob'인 String 객체의 참조를 저장
void main() {
String strName = 'Bob';
Object name = strName;
// String t = name; // error
}
유추될 타입을 직접 지정 가능
- nullable 변수의 디폴트 값은 null로 초기화
void main() {
int? val;
assert(val == null);
}
숫자 유형도 null로 초기화된다. 숫자 또한 Dart에서는 객체이기 때문.
* 개발 단계에서 assert는 예외를 던진다.
void main() {
int val;
print(val);
}
Error: Non-nullable variable 'val' must be assigned before it can be used.
print(val); // error
null safety 변수는 사용되기 전에 값이 지정되어야 한다.
void main() {
int val;
if(1 == 1) {
val = 3;
} else {
val = 4;
}
print(val);
}
반드시 선언하자마자 초기화할 필요는 없다.
최상위 및 클래스 변수는 느리게 초기화된다. 변수가 처음 사용될 때 초기화 코드 실행된다.
- late
선언 후에 초기화되는 non-nullable 변수를 선언하거나, 변수를 느리게 초기화할 때 사용.
String val;
void main() {
val = 'hello';
print(val);
}
Error: Field 'val' should be initialized because its type 'String' doesn't allow null.
val이 사용 전에 초기화되었다고 확신할 수 있지만, 다트에서는 허용하지 않는다.
이런 경우 late 키워드를 사용하면된다.
late String val;
void main() {
val = 'hello';
print(val);
}
만약 val이 사용하기 전에 초기화되지 않았다면,
late String val;
void main() {
print(val);
}
런타임에 에러가 발생한다.
late를 선언하고 바로 초기화하면,
사용되지 않을 수 있는데 초기화 비용이 큰 경우,
인스턴스 변수를 초기화하고 있고 initializer에서 this에 대한 액세스 권한이 필요한 경우에 이점이 있다.
late String temperature = readThermometer();
temperature가 사용되지 않으면, readThermomoter는 호출되지 않는다.
- final, const
변수를 변경하지 않으려면, var 대신 또는 type에 추가하여 final과 const를 사용한다.
final 변수는 한 번만 설정 가능.
const는 컴파일 타임에 상수.
void main() {
final name = 'Bob';
final String nickname = 'Bobby';
name = 'test';
}
Error: Can't assign to the final variable 'name'.
final 변수는 변경할 수 없다.
void main() {
const val = 1234;
const String strVal = '1234';
}
컴파일 타임 상수를 원한다면 const를 사용한다.
클래스 레벨에서는 static const를 사용하자.
추가 내용 참고
https://dart.dev/guides/language/language-tour#final-and-const
- Built-in types
Numbers(int, double), Strings(String), Booleans(bool), Lists(List), Sets(Set), Maps(Map), Runes, Symbols, null
리터럴을 이용하여 객체를 만드는 것을 포함한다. 예를 들어, 'this is a string'은 string 리터럴, true는 boolean 리터럴.
일부 타입은 다트에서 특별한 역할을 가진다.
Object : 모든 다트 클래스의 수퍼클래스(Null 제외)
Enum : 모든 열거형의 수퍼클래스
Future와 Stream : 비동기 지원에 사용됨
Iterable : for-in 루프, 동기 generator 함수에서 사용됨
Never : 표현식이 실행을 성공적으로 완료할 수 없음을 나타냄. 항상 예외를 던지는 함수에서 가장 자주 사용됨
dynamic : 스태틱 검사 비활성화할 것임을 나타냄. 보통 대신 Object 또는 Object?를 사용
void : 값이 사용되지 않음을 나타냄. 종종 반환 타입에 사용됨
Object, Object?, Null, Never 클래스는 클래스 계층에서 특별한 역할을 가진다.
- Numbers
다트의 숫자는 두 가지 방식으로 나타난다.
int : 플랫폼에 따라 64비트 이하의 정수 값. 네이티브 플랫폼에서 값은 (-2^63) ~ (2^63 - 1)이 될 수 있다. 웹에서 정수 값은 자바스크립트 숫자(소수 부분이 없는 64비트 부동소수점 값)로서 표현되고, (-2^53) ~ (2^53 - 1)이 될 수 있다.
double : IEEE 754 표준에서 지정한 64비트 부동소수점 숫자.
int와 double은 num의 서브타입이다. num 타입은 사칙연산과 같은 기본 연산을 포함하고, abs(), ceil() 등의 메소드를 찾을 수 있다.
void main() {
var num = -3.5;
print(num.abs());
}
>> 와 같은 비트 연산자는 int 클래스에 정의되어 있다.
void main() {
var num = 1;
print(num << 10); // 1024
}
num과 서브타입에 원하는게 없다면, dart:math 라이브러리에 있을 수도 있다.
Integers는 소수점이 없는 숫자이다.
숫자가 소수점을 포함하면, 그것은 double이다.
var x = 1;
var hex = 0xDEADBEEF;
var exponent = 8e5;
var y = 1.1;
var exponents = 1.42e5;
숫자를 num으로 선언할 수도 있다. 이렇게 하면, 변수는 integer와 double 값을 모두 가질 수 있다.
void main() {
num x = 1; // int 또는 var 타입으로 선언하면 컴파일 에러
x += 1.5;
print(x);
}
정수 리터럴은 필요할 때 자동으로 double로 변환될 수 있다.
double z = 1; // double z = 1.0 과 동일
문자열을 숫자로, 숫자를 문자열로 바꿀 수 있다.
// String -> int
var one = int.parse('1');
assert(one == 1);
// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);
// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
int 타입은 시프트(<<, >>, >>>), 보수(~), AND(&), OR(|), XOR(^) 연산자를 지원한다.
assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 | 4) == 7); // 0011 | 0100 == 0111
assert((3 & 4) == 0); // 0011 & 0100 == 0000
리터럴 숫자는 컴파일 타임 상수이다.
피연산자가 숫자로 평가되는 컴파일 타임 상수라면, 많은 산술 표현식도 컴파일 타임 상수이다.
const msPerSecond = 1000;
const secondsUntilRetry = 5;
const msUntilRetry = secondsUntilRetry * msPerSecond;
- Strings
Dart 문자열은 UTF-16 코드 단위로 표시된다.
작은 따옴표나 큰 따옴표를 이용하여 string을 만들 수 있다.
var x = '\'hello' + "wolrd\"";
print(x); // 'hellowolrd"
${expression}을 이용하여 문자열 내에 표현식 값을 넣을 수 있다.
표현식이 식별자라면, {}를 생략할 수 있다.
객체에 해당하는 문자열을 가져오기 위해 Dart는 객체의 toString() 메소드를 호출한다.
var str = 'world';
print('hello $str'); // hello world
print('hello ${str.toUpperCase()}'); // hello WORLD
인접한 문자열 리터럴 또는 + 연산자를 이용하여 문자열을 연결할 수 있다.
var str1 = "hello" 'world';
var str2 = 'hello' + "world";
print(str1 + str2);
3개의 따옴표를 이용하여 멀티라인 문자열을 만들 수 있다.
var str1 = '''
hello
world
''';
var str2 = """
hello
world
""";
'플러터' 카테고리의 다른 글
Dart 문법 공부 - 6 (0) | 2022.06.01 |
---|---|
Dart 문법 공부 - 5 (0) | 2022.05.30 |
Dart 문법 공부 - 4 (0) | 2022.05.29 |
Dart 문법 공부 - 3 (0) | 2022.05.29 |
Dart 문법 공부 - 2 (0) | 2022.05.28 |