2024년 11월 9일 토요일

Flutter #0

[Flutter 교육]


Dart vs JavaScript 타입 시스템 비교

1. 기본 타입 차이

숫자 타입

// Dart
int integerNumber = 42;        // 정수
double floatingPoint = 3.14;   // 부동 소수점
num dynamicNumber = 123;       // 동적 숫자 타입

// JavaScript
let number = 42;              // 모든 숫자가 64비트 부동 소수점
let integer = Math.floor(42); // 정수 처리는 명시적 변환 필요

주요 차이점:

  1. Dart는 정수와 부동 소수점을 명확히 구분
  2. JavaScript는 모든 숫자를 부동 소수점으로 처리
  3. 정밀도 차이:
    • Dart: int는 64비트 정수
    • JavaScript: 53비트 정수 정밀도

실제 영향:

// Dart에서 안전한 정수 계산
int largeNumber = 9007199254740992;  // 2^53
int result = largeNumber + 1;        // 정확한 결과

// JavaScript에서 정밀도 손실
let largeNumber = 9007199254740992;  // 2^53
let result = largeNumber + 1;        // largeNumber와 동일 (정밀도 손실)

2. 널 안전성

Dart의 널 안전성

String nonNullable = "Hello";     // null 불가
String? nullable = null;          // null 가능
int? nullableNumber;              // 자동으로 null로 초기화

void processString(String? text) {
  if (text != null) {
    print(text.length);  // 널 체크 후 안전한 접근
  }
}

JavaScript의 널 처리

let text = null;                  // 모든 변수가 nullable
console.log(text?.length);        // 옵셔널 체이닝 필요

// 타입스크립트를 사용하는 경우
let nonNullable: string = "Hello";
let nullable: string | null = null;

주요 차이점:

  1. Dart는 컴파일 타임에 널 안전성 보장
  2. JavaScript는 런타임에 널 체크 필요
  3. Dart의 널 안전성은 언어 레벨에서 지원

3. 제네릭 처리

Dart의 제네릭

// 컴파일 타임에 타입 검사
class Box<T> {
  final T value;
  Box(this.value);

  T getValue() => value;
}

// 구체적인 타입 지정
Box<int> numberBox = Box(42);
Box<String> stringBox = Box("Hello");

// 타입 제한
class NumberBox<T extends num> {
  final T value;
  NumberBox(this.value);
}

JavaScript의 제네릭

// 런타임에 타입 정보 소실
class Box {
  constructor(value) {
    this.value = value;
  }

  getValue() {
    return this.value;
  }
}

// 타입 정보 없음
const numberBox = new Box(42);
const stringBox = new Box("Hello");

주요 차이점:

  1. Dart는 런타임에도 제네릭 타입 정보 유지
  2. JavaScript는 타입 삭제(type erasure) 발생
  3. Dart는 제네릭 제약 조건 지원

4. 함수 타입

Dart의 함수 타입

// 명시적 함수 타입
typedef StringProcessor = String Function(String);

// 함수 타입 매개변수
void processString(StringProcessor processor) {
  print(processor("Hello"));
}

// 함수 타입 검사
StringProcessor toUpperCase = (String s) => s.toUpperCase();

JavaScript의 함수 타입

// 함수 타입 정보 없음
function processString(processor) {
  console.log(processor("Hello"));
}

// 런타임 타입 체크 필요
const toUpperCase = s => s.toUpperCase();

주요 차이점:

  1. Dart는 컴파일 타임 함수 타입 검사
  2. JavaScript는 런타임에만 함수 타입 확인 가능
  3. Dart는 함수 시그니처 강제

5. 인터페이스와 추상 클래스

Dart의 인터페이스

// 명시적 인터페이스
abstract class Printable {
  void print();
}

// 암시적 인터페이스
class Document implements Printable {
  @override
  void print() {
    // 구현
  }
}

// 다중 인터페이스 구현
class AdvancedDocument implements Printable, Saveable {
  @override
  void print() { }

  @override
  void save() { }
}

JavaScript의 인터페이스

// 인터페이스 개념 없음
class Document {
  print() {
    // 구현
  }
}

// 런타임 체크 필요
class AdvancedDocument extends Document {
  save() {
    // 구현
  }
}

주요 차이점:

  1. Dart는 명시적 인터페이스 지원
  2. JavaScript는 인터페이스 개념 없음
  3. Dart는 다중 인터페이스 구현 가능

6. 타입 추론

Dart의 타입 추론

// 지역 변수 타입 추론
var number = 42;          // int로 추론
var text = "Hello";       // String으로 추론
final list = <int>[];     // List<int>로 추론

// 제네릭 타입 추론
Map<String, int> scores = {
  'John': 100,
  'Jane': 95,
};

JavaScript의 타입 추론

// 동적 타이핑
let number = 42;          // 타입 변경 가능
let text = "Hello";       // 타입 변경 가능

// 런타임에 타입 결정
const scores = {
  'John': 100,
  'Jane': 95,
};

주요 차이점:

  1. Dart는 강력한 타입 추론 시스템
  2. JavaScript는 동적 타이핑
  3. Dart의 타입 추론은 불변

7. 컬렉션 타입

Dart의 컬렉션

// 타입이 있는 컬렉션
List<int> numbers = [1, 2, 3];
Set<String> uniqueNames = {'John', 'Jane'};
Map<String, int> ages = {'John': 30, 'Jane': 25};

// 제네릭 컬렉션 처리
void processNumbers(List<num> numbers) {
  numbers.forEach((n) => print(n * 2));
}

JavaScript의 컬렉션

// 동적 타입 컬렉션
const numbers = [1, 2, 3];           // 혼합 타입 가능
const uniqueNames = new Set(['John', 'Jane']);
const ages = {'John': 30, 'Jane': 25};

// 타입 체크 필요
function processNumbers(numbers) {
  numbers.forEach(n => {
    if (typeof n === 'number') {
      console.log(n * 2);
    }
  });
}

주요 차이점:

  1. Dart는 타입이 있는 컬렉션 강제
  2. JavaScript는 혼합 타입 허용
  3. Dart는 컬렉션 타입 안전성 보장

8. 타입 변환과 검사

Dart의 타입 변환

class Animal {}
class Dog extends Animal {}

void processAnimal(Animal animal) {
  if (animal is Dog) {
    // 자동 타입 승격
    animal.bark();  // Dog 타입으로 인식
  }
}

// 명시적 타입 캐스팅
Animal animal = Dog();
(animal as Dog).bark();

JavaScript의 타입 변환

class Animal {}
class Dog extends Animal {
  bark() {}
}

function processAnimal(animal) {
  if (animal instanceof Dog) {
    // 타입 보장 없음
    animal.bark();
  }
}

// 런타임 체크 필요
const animal = new Dog();
if (animal instanceof Dog) {
  animal.bark();
}

주요 차이점:

  1. Dart는 스마트 캐스팅 지원
  2. JavaScript는 수동 타입 체크 필요
  3. Dart는 타입 안전한 캐스팅 제공


출처 : https://cheddar-sparrow-aba.notion.site/Dart-vs-JavaScript-13997e0a8ff38043a400c9702b16614f


Flutter #0

[Flutter 교육] Dart vs JavaScript 타입 시스템 비교 1. 기본 타입 차이 숫자 타입 // Dart int integerNumber = 42; // 정수 double floatingPoint = 3.14; // 부...