본문 바로가기
프로젝트/틱톡 클론

[틱톡 클론-02] Dart 강의 듣기

by 1005ptr 2023. 4. 23.
반응형

 

[코드팩토리] [입문] Dart 언어 4시간만에 완전정복

 

[무료] [코드팩토리] [입문] Dart 언어 4시간만에 완전정복 - 인프런 | 강의

이 강의를 통해 Dart 언어를 배우면 Flutter를 시작할 수 있을 정도의 수준으로의 업그레이드가 가능합니다!, - 강의 소개 | 인프런

www.inflearn.com


Dart 언어 수업을 들었다.

Dart 언어는 뭔가 내가 아는 언어들이 이것저것 짬뽕되어있는 느낌이다.

자바같다고 느낀 부분은 Future같이 자바에서 봤던 개념들이 포함돼있어서 그랬던거 같다.

그 외에는 타입스크립트랑 비슷하다고 느껴진다.

클래스로 쓰는 부분에서는 자바같은 느낌도 있다.

자바는 모든게 클래스지만 여기서는 함수로만 쓸수도 있다.

 

기본기


타입

  • 기본 타입으로 int, double, String, bool이 있다.
  • 특이한 부분은 var 라는게 있고 dynamic이라는게 있다.
  • var는 타입이 한번 정해지면 유지된다. 타입 추론으로 값에 따라 타입이 정해지는 것. 컴파일 타임에 타입이 고정됨
  • dynamic은 값이 지정된 이후에도 타입이 변할 수 있다. 런타임 가변 타입
  • 나는 굳이 필요없으면 타입 추론이나 가변 타입은 사용하지 않는 편이다.
  • 기본 타입을 사용하자~

변수의 널 체크

  • 널 관련해서 타입스크립트랑 비슷한 문법이 존재한다.
  • 변수 뒤에 물음표를 붙이면 널러블한 변수
  • 변수 뒤에 느낌표를 붙이면 반드시 값이 있다. (값이 있다는 보장. 널체크를 안해도 된다.)
  • 참고로 나는 느낌표 쓰는걸 싫어한다.

final 키워드, const 키워드

  • 둘다 상수를 선언하기 위한 키워드인데 둘의 차이가 있다.
  • const같은 경우 컴파일 타임에 값을 알고 있어야 한다.
  • final같은 경우 컴파일 타임에 값을 알지 않아도 된다.
  • 빌드 타임의 값을 알아야 한다는 것은 상수값만 넣을 수 있다는 것이다. 변수나 함수의 실행 결과를 넣을 수 없다는 것이다.
  • 두개가 나뉘어져 있는 이유는 성능 향상 보다는 시맨틱적인 이유가 담겨있다고 이해하면 된다.
    • const는 실행 중에 변경될 필요가 없는 값
    • final은 실행 중에 값이 결정되는 값
  • const를 쓸 수 있는 경우 const를 쓰고 아니면 final을 쓴다.
더보기
  • 실행 시점 상수 평가
    • const: 컴파일 타임에 상수를 평가하고 실행 중에 변경될 수 없습니다. 이는 컴파일러가 상수를 메모리에 캐시하고 상수에 대한 참조를 그 값으로 대체함으로써 실행 속도를 향상시킵니다.
    • final: 실행 중에 상수를 계산할 수 있습니다. 따라서 런타임에 값이 결정됩니다.
  • 사용 위치 제한
    • const: const는 상수로만 초기화될 수 있으며, 클래스, 변수, 생성자 등 모든 곳에서 사용될 수 있습니다.
    • final: final은 런타임에 초기화될 수 있으며, 변수 또는 클래스 멤버 필드에서만 사용될 수 있습니다.
  • 메모리 할당
    • const: 컴파일 타임에 상수를 평가하고 실행 중에 변경될 수 없으므로, 상수 값은 프로그램 시작 시점에 메모리에 할당됩니다.
    • final: final 변수는 런타임에 값을 계산할 수 있으므로, 변수 값은 변수가 처음 사용될 때 메모리에 할당됩니다.
  • 따라서, const는 런타임에 계산될 필요가 없는 상수를 정의할 때 사용되며, final은 런타임에 계산될 필요가 있는 값을 저장할 때 사용됩니다.

함수

  • 함수에 옵셔널 파라미터를 지정할떄는 대괄호로 감싸서 넣어준다. 옵셔널 파라미터에는 기본값을 넣어줘야 한다.
addNumbers(int x, [int y = 1, int z = 2])
{
	...
}
  • namedParameter라는 문법으로 파라미터를 지정하면 선언도 다르고 입력할떄도 항상 이름을 지정해줘야 한다.
  • 함수 파라미터 지정시에 중괄호로 감싸서 넣어줌 required안적으면 옵셔널해짐 ({required int x, required int y, int z})
addNumber({
    required int x,
    required int y,
    int z
})

기타

  • 타입 체크에 is 키워드가 있음
  • List, Map, Set 컬렉션을 제공한다.

객체지향 프로그래밍

생성자를 직접 적지 않고 변수 명만 적는 문법이 잇다.

  • 생성자(this.변수1, this.변수2);
  • 생성자에서 주로 하는 일이 로직같은거 없이 파라미터 값을 멤버 변수에 넣는거다 보니까
  • 작업 편의성을 위해 만든 문법이라고 보인다.
Class Idol {
    String name;
    List<String> members;
    
    Idol(this.name, this.members);
}

immutable 프로그래밍이라는게 있다.

  • 이건 또 리액트에서 나왔던 개념이네
  • 대부분의 변수를 final로 선언하는 버릇을 들이자.
  • State라는것도 있네. 나중에 상태 관리 라이브러리도 있어서 Bloc 같은거 쓰려면 immutable하게 짜야된다고 한다.
  • 불변성을 지켜야 한다고 하는데 이게 필수인가? GPT 한테 물어봤다.
  • 필수라고 한다.
더보기

Q1) 플러터 개발할떄 불변성을 지켜서 개발해줘야해?

플러터(Flutter)는 Dart 언어로 개발된 모바일 애플리케이션 프레임워크입니다. Dart 언어는 기본적으로 불변성(Immutability)을 적극적으로 지향하는 언어입니다. 불변성을 지키면 객체가 변경되는 것을 방지할 수 있기 때문에 코드를 더 안정적이고 예측 가능하게 만들어주는 장점이 있습니다.

따라서 플러터 애플리케이션을 개발할 때도 불변성을 지켜서 개발하는 것이 권장됩니다. 이를 위해서는 변경 가능한 상태를 최소화하고, 불변성을 유지하기 위한 클래스와 함수를 사용해야 합니다. 또한, 플러터에서 제공하는 상태 관리 라이브러리인 Provider나 Bloc과 같은 라이브러리를 사용하면, 불변성을 보장하면서 상태를 관리할 수 있습니다.

불변성을 지키면 코드의 안정성과 가독성을 향상시키는 것은 물론, 플러터 애플리케이션의 성능을 향상시키는 효과도 있습니다. 특히, Flutter의 위젯은 불변성을 기반으로 작동하므로, 상태가 변경되지 않는 경우, 새로운 위젯을 렌더링하지 않고 이전에 렌더링된 위젯을 재사용함으로써 성능을 향상시킬 수 있습니다.

Q2) 불변성을 안지켜도 되긴 된다는 이야긴건가?

불변성을 지키지 않아도 플러터(Flutter) 애플리케이션을 개발할 수는 있지만, 불변성을 지키는 것이 좋은 개발 습관입니다. 불변성을 지키면 코드가 더 안정적이고 예측 가능하며, 디버깅과 테스트를 더 쉽게 할 수 있습니다. 또한, 불변성을 지키면 성능 향상도 기대할 수 있습니다.

반면에, 불변성을 지키지 않으면 코드가 예측 불가능해지고, 디버깅과 테스트가 어려워집니다. 불변성을 지키지 않으면 객체의 상태가 언제든지 변경될 수 있기 때문에, 예상치 못한 버그가 발생할 가능성도 높아집니다. 또한, 플러터는 위젯을 불변성을 기반으로 작동하기 때문에, 상태가 변경되지 않는 경우, 새로운 위젯을 렌더링하지 않고 이전에 렌더링된 위젯을 재사용함으로써 성능을 향상시킬 수 있습니다. 따라서, 불변성을 지켜주는 것이 플러터 애플리케이션을 개발하는 데 있어서 좋은 습관이라고 할 수 있습니다.

Gettter / Setter

  • get이라는 키워드가 있다. getter 함수를 만들때 쓰는듯
  • setter 만들때 쓰는 set이라는 키워드도 있는데 아 이거는 사전 정의되어있는 함수 형태라고 이해가 된다. 특정 형태의 function(파라미터가 하나에 void인 함수)
  • get, set 키워드 쓸떄는 함수명 옆에 괄호를 안친다.
  • 함수와의 차이는 뉘앙스 차이다.
  • 로직이 없는 단순 get,set인지 로직이 있는지 차이로 구분해서 사용하면 될듯
List<String> members;

String getFirstMember() {
    return this.members[0];
}

String get firstMember {
    return this.members[0];
}

언더스코어(_) 접근제어

  • 클래스 명 앞에 언더스코어를 넣으면 접근 제어가 된다. private 처리가 된다고 함.
  • 변수, 함수 클래스 등 모두 언더스코어 문법이 있다.
  • public, private 키워드가 아예 없고 접근 제어 하려면 언더스코어를 사용해야 한다고 함

비동기 프로그래밍

Future

  • Furue는 또 자바에서 봤던 코드다
  • 비동기 함수는 Future를 반환한다.
  • 함수 뒤에 async 넣고 Future 앞에 await를 넣는다. 그럼 동기처럼 동작한다.
  • await는 Future를 리턴해주는 함수에만 달 수 있다.
  • Future<void>라고 적으면 값을 반환하지 않는 Future 함수
  • Future값을 반환하는 함수인 경우 직접 Future를 감싸는 작업 할 필요 없이 알아서 해준다.

Stream

  • Stream이 있네 Stream은 자바다
  • import 'dart:async'; 해서 StreamController를 가져올 수 있다.
  • yield로 값을 반환할 수 있다.
  • listen으로 값을 읽어 들일 수 있다.
  •  
  • sync.add로 값을 추가할 수 있다.
  • listen 앞에 where을 넣어서 listen의 조건을 추가할 수 있다.

Stream을 반환하는 함수

  • Stream을 반환하고 async* 설정된 함수에 yield라고 선언된 값을 실행하면 함수 호출 반환값에 listen을 달 수 있다.
void main() {
    calculate(1).listen((val){
        print('calculate(1) : ${val}');
    });
}

Stream<int> calculate(int value) async* {
    for(int i = 0 ; i < 5 ; i++){
        yield value * i;
    }
}

 

  • stream을 async 하는 방법?
    • Stream간의 동기 처리하는 방법에 대한 이야기
    • 새 Stream 함수를 만들고
    • 호출할 Stream함수에 yield* 을 하고 함수를 호출한다.
    • 스트림이 끝나고 나야 다음 스트림이 실행됨

사실 이렇게 Stream이나 Future를 생짜로 쓰는 일은 잘 없다고 한다.

나중에 플러그인, 오픈소스 같은걸 쓰면 이런걸 직접 쓰지는 않지만 알아두면 좋다~

반응형

댓글