[FLUTTER] DART 언어 기초과정 - 4 / A Tour of the Dart Language
플러터란 ? 구글에서 개발한 크로스 플랫폼 앱 개발 프레임워크이다. 언어는 구글이 개발한 Dart 를 사용한다. 안드로이드, iOS, Web, Desktop 을 지원하며 구글의 차기 OS Fuchsia의 메인개발환경이 된다고 한다.
- 최대한 내용을 줄여 표현했습니다. (너무 길면 이해가 힘들고, 어느정도 수준이 되어야 이해가 되기 때문)
- 혹시 궁금하시다면 위 링크를 참조 하시면 됩니다.
이전 편
- [FLUTTER] DART 언어 기초과정 - 3 / A Tour of the Dart Language
- [FLUTTER] DART 언어 기초과정 - 2 / A Tour of the Dart Language
- [FLUTTER] DART 언어 기초과정 - 1 / A Tour of the Dart Language
50. 클래스 변수와 메소드
50.1. static(고정된) 변수
- 정적 변수는 상태값 또는 상수값 표현에 유용합니다.
- static 변수는 호출 전까지 초기화 되지 않습니다.
- static 변수의 표현은
lowerCamelCase
형태를 지향합니다. (자바랑은 좀 다르네요 : 대문자 + 언더스코어 )
class Queue {
static const initialCapacity = 16;
// ···
}
void main() {
assert(Queue.initialCapacity == 16);
}
50.2. static(고정된) 메소드
- static 메소드를 통해 손쉽게 호출 할 수 있습니다.
- 공통적으로 또는 널리 사용되는 유틸리티 및 기능에 대해서는 정적 방법 대신 최상위(top-level) 기능을 사용하는 것이 좋습니다.
ex) top-level function : main과 동일선상에 함수를 생성해 주면 됨
int plus(a, b){
return a+b;
}
import 'dart:math';
class Point {
num x, y;
Point(this.x, this.y);
static num distanceBetween(Point a, Point b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
}
void main() {
var a = Point(2, 2);
var b = Point(4, 4);
var distance = Point.distanceBetween(a, b);
assert(2.8 < distance && distance < 2.9);
print(distance);
}
51. Generics(제네릭)
List<E>
이런 형태로 표현됨 / 리스트 내부 문자로는E, T, S, K, V
같은 문자를 사용함.- 제네릭 형식을 올바르게 지정하면 코드를 더 잘 생성 할 수 있습니다.
- 제네릭을 사용하여 코드 중복을 줄일 수 있습니다.
아래와 같이 목록(List)의 타입을 String 으로 지정했기 때문에, 다른 타입
42
라는 숫자를 추가하려면 오류가 발생합니다.
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
names.add(42); // 오류 발생
캐시에서 값을 설정/추출할 때 StringCache 라고 명명하면, 매번 각각의 다양의 타입을 만들때마다 클래스를 만들어야 됩니다.
abstract class StringCache {
String getByKey(String key);
void setByKey(String key, String value);
}
하지만 제네릭을 활용하면 다양한 타입을 활용할 수 있습니다. 클래스 생성시 T에 타입을 지정하면 해당 부분이 치환되어 자동으로 적용됩니다.
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
51.2 사용 예시
// collection 형태
var names = <String>['Seth', 'Kathy', 'Lars'];
var pages = <String, String>{
'index.html': 'Homepage',
'robots.txt': 'Hints for web robots',
'humans.txt': 'We are people, not machines'
};
// 파라미터 타입 생성자 형태
var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
var nameSet = Set<String>.from(names);
var views = Map<int, View>();
51.3 파라미터 타입 제한
- extends 구문과 조합하여 활용
T extends SomeBaseClass
SomeBaseClass 클래스를 상속받은 형태만 사용가능 함 이라고 지정할 수 있다.
class Foo<T extends SomeBaseClass> {
// Implementation goes here...
String toString() => "Instance of 'Foo<$T>'";
}
class Extender extends SomeBaseClass {...}
var extenderFoo = Foo<Extender>(); // 정상
var foo = Foo<Object>(); // 오류
51.4 generic 메소드 사용방법
여기서 첫 번째 (
<T>
)의 제네릭 형식 매개 변수를 사용하면 여러 위치에서 형식 인수 T를 사용할 수 있습니다.
- 함수의 리턴 형식 (
T
). - 파라미터 유형 (
List <T>
). - 지역 변수의 유형 (
T tmp
).
T first<T>(List<T> ts) {
// 초기화 작업, 오류점검 등등 수행
T tmp = ts[0];
// 추가적으로 점검할 것 또는 작업 처리 등
return tmp;
}
52. 라이브러리
가져 오기(import) 및 라이브러리(library) 지시문을 사용하면 모듈 식 공유 가능 코드 형태를 구성할 수 있습니다. 밑줄
_
로 시작하는 식별자는 라이브러리 내부에서만 볼 수 있으며, 라이브러리는 패키지를 사용하여 배포 할 수 있습니다.
52.1 라이브러리 사용방법
dart:html
라이브러리를 사용하려면 아래와 같이 프로그램 최상단에 기술하면 됩니다.
import 'dart:html';
- dart에서 제공하는 빌트인 라이브러리 같은경우
dart:
를 사용합니다. - 패키지(pub tool에서 다운받은 패키지) 또는 파일 시스템 내부 경로에 접근하고자 하는 경우
package:
를 사용 합니다. - URI와 같은 형태로 해당 프리픽스 (dart:, package: ) 뒤에 사용하고자 하는 스키마 정보를 넣어주면 됩니다.
import 'package:test/test.dart';
52.2 접두사(prefix) 활용
- 각 라이브러리에 동일 top-level 함수가 존재하는 경우
as
를 활용하여 중복되는 요소에 접근할 수 있도록 도와준다.
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// lib1 에서 사용되는 Element
Element element1 = Element();
// lib2 에서 사용되는 Element
lib2.Element element2 = lib2.Element();
52.3 필요한 일부 라이브러리만 가져오기
// foo 만 가져온다
import 'package:lib1/lib1.dart' show foo;
// foo 를 제외한 나머지 모두를 가져온다
import 'package:lib2/lib2.dart' hide foo;
52.4 느리게 라이브러리 가져오기
- 앱의 초기 기동 시간을 줄이고자 하는 경우
- A / B 테스트를 수행하고자 라이브러리 부분 교체 테스트 진행을 하고자 하는 경우
- 옵션 화면, 다이얼로그 같이 잘 사용하지 않는 화면/기능을 로딩하고자 할 때
// deferred as 를 사용하여 라이브러리를 늦게 읽어들인다
import 'package:greetings/hello.dart' deferred as hello;
// 필요할 때 라이브러리 식별자(hello)를 활용하여 로딩을 수행한다.
Future greet() async {
await hello.loadLibrary(); // 라이브러리 로딩 될 때까지 대기
hello.printGreeting(); // 로딩 이후 해당 기능 호출
}
참조사항
- loadLibrary() 를 여러번 호출하더라도 라이브러리는 1번만 로딩 됩니다.
- 라이브러리 내부 상수, 내부 타입 등 모든 것들은 라이브러리가 로딩되기 전까지는 사용할 수 없습니다.
- loadLibrary() 는 Future 를 리턴합니다. ( javascript의 Promise와 비슷한 느낌이라 생각하면 됨 )
52.5 라이브러리 구현방법
- 패키지 생성방법 을 참조 바랍니다.
아래 내용이 포함되어 있습니다.
- 라이브러리 소스코드 구성하는 방법
export
지시자 사용방법- 언제
part
지시자를 사용하나 ? - 언제
library
지시자를 사용하나 ?
53. 비동기(async) 지원
다트 라이브러리는 Future 또는 Stream 객체를 반환하는 함수로 가득합니다. 이러한 함수는 비동기식입니다.
시간이 많이 소요되는 연산 (예 : I/O)을 설정 한 후 반환되며, 해당 연산이 완료 될 때까지 기다리지 않고 반환됩니다.
async 및 await 키워드는 비동기 프로그래밍을 지원하므로 동기 코드와 비슷한 비동기 코드를 작성할 수 있습니다.
53.1 Future 처리
- 비동기 함수는
async
지시자를 넣어 함수 내부에서await
구문을 사용할 수 있습니다. await
: 해당 호출 구문이 완료 될 때까지 대기한 이후 결과를 리턴함.async
함수 내부에서는await
을 여러번 사용해도 무방 합니다.Future
를 리턴하는 경우 해당 기능을 활용할 수 있습니다.(아래 좀 더 설명 예정)
Future checkVersion() async {
var version = await lookUpVersion();
// version 정보를 가지고 뭔가를 수행
}
53.2 비동기함수(async function) 선언
// 동기
String lookUpVersion() => '1.0.0';
// 비동기
Future<String> lookUpVersion() async => '1.0.0';
53.3 스트림 처리(Handling Streams)
- (await for) : 스트림에서 값이 도착 할 때까지 대기
- 수신한 값(varOrType) 을 가지고 작업 처리
- 스트림이 닫힐 때까지 1과 2를 반복합니다.
await for (varOrType identifier in expression) {
// 해당 스트림에서 값을 보내줄 때(emit) 마다 수행
}
사용 예시
Future main() async {
// ...
await for (var request in requestServer) {
handleRequest(request);
}
// ...
}
54. 제너레이터:생성기(Generators)
느리게 값을 열거형으로 생성하는 형태의 경우 생성기함수(Generator function)을 사용하는 것을 고려 해봄직 합니다.
동기 생성기 : 열거형(Iterable) 개체 반환
비동기 생성기 : 스트림(Stream) 개체 반환
몸체(body)에
sync*
(비동기)를 마킹하고,yield
(양보)를 사용하여 값을 배달 합니다.
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
- 몸체(body)에
async*
(비동기)를 마킹하고,yield
(양보)를 사용하여 값을 배달 합니다.
Stream<int> asynchronousNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
순환 형태의 경우
sync*
와yield*
를 사용하여 성능을 향상시킬 수 있습니다.
Iterable<int> naturalsDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* naturalsDownFrom(n - 1);
}
}
55. 부를수 있는 클래스(Callable classes)
call 메소드를 사용하여 해당 클래스를 호출(call)할 수 있습니다.
- 클래스를 생성
- 변수화 한 이후 값을 넣어 호출
class WannabeFunction {
call(String a, String b, String c) => '$a $b $c!';
}
main() {
var wf = new WannabeFunction();
var out = wf("Hi","there,","gang");
print('$out');
}
56. typedef
Dart에서 함수는 문자열이고 숫자는 객체와 같은 객체입니다. typedef 또는 함수 유형 별명은 함수 유형에 필드 및 리턴 유형을 선언 할 때 사용할 수있는 이름을 제공하며, 함수 유형이 변수에 지정 될 때 유형 정보를 보유합니다.
- 현재 함수(Function)에 한정적으로 적용되며, 향후 변경될 예정입니다.
57. metadata
메타 데이터를 사용하여 코드에 대한 추가 정보를 제공할 수 있습니다.(메타 데이터의 어노테이션은 문자 @로 시작합니다.)
@deprecated : 사라질 예정 (이전 메소드 사용자에 대한 배려)
class Television {
/// 사라질 예정(Deprecated) : 대신 turnOn 매소드를 사용 바랍니다.
@deprecated
void activate() {
turnOn();
}
/// TV 파워 키기
void turnOn() {...}
}
@Todo : 할 일
import 'todo.dart';
@Todo('seth', 'make this do something')
void doSomething() {
print('do something');
}
58. 주석(Comment)
한줄짜리
void main() {
// TODO: AbstractLlamaGreetingFactory 로 리펙토링 하자 !
print('Welcome to my Llama farm!');
}
멀티라인 주석
void main() {
/*
* 많은 일 을 해야 됨. 닭을 키우는 것을 고려
Llama larry = Llama();
larry.feed();
larry.exercise();
larry.clean();
*/
}
59. 문서주석 (Document Comments)
///
또는/**
를 사용하여 내용을 기록합니다.[파라미터명]
을 사용하여 해당 함수의 파라미터를 지칭할 수 있습니다.
/// A domesticated South American camelid (Lama glama).
///
/// Andean cultures have used llamas as meat and pack
/// animals since pre-Hispanic times.
class Llama {
String name;
/// Feeds your llama [Food].
///
/// The typical llama eats one bale of hay per week.
void feed(Food food) {
// ...
}
/// Exercises your llama with an [activity] for
/// [timeLimit] minutes.
void exercise(Activity activity, int timeLimit) {
// ...
}
}
맺음말
4회로 나눠 기초 개발 가이드를 설명 드렸네요 :) 둘러보기식 설명이긴 하지만 프로그램을 첨 하시는 분들께는 정말
이건 뭐지?!
라고 생각할 만큼의 내용이네요 그리고 저 또한 dart에 대해 숙련자가 아닌지라 100%이해하고 요약하기 보단 번역기를 돌린 부분도 상당수 포함되어 있긴합니다. 하지만 중간중간 나오는 예제 소스코드를 따라해 보면서 이곳까지 오셨다면 분명 실력향상과 첨에는 dart가 뭐지 ? 라고 했다가 이젠 어느정도 느낌은 오시지 않았을까 라고 생각해 봅니다.이후로는 여기서 알려준 기초 설명을 토대로 하나 둘씩 살을 붙여 가면서 반복 학습을 진행하도록 해보겠습니다.
읽기 힘든 글 읽어주셔서 (또는 눈팅 이라도) 감사합니다
관련 글 링크
@flutters : 제가 작성한 글 중 fluter 관련 글만 모아서 리스팀 처리
관련글(영문)
연재글
- [FLUTTER] DART 언어 기초과정 - 3 / A Tour of the Dart Language
- [FLUTTER] DART 언어 기초과정 - 2 / A Tour of the Dart Language
- [FLUTTER] DART 언어 기초과정 - 1 / A Tour of the Dart Language
좀 공부하려 했다가...ㅋㅋ
스몬게임을 하기로 했습니다.
저에겐 너무 고급 영역
전 행님 만들어 논거 쓰는걸로~~~ ㅎ
:) 그럼 스몬에서 봐용 ㅎㅎ
Posted using Partiko Android
다트하려면 이런 언어를 배워야 하는건가요? ㅠㅠ
딩동댕 ! 정 가운데를 맞추면 됩니다. 그렇다고 가운데님께 던지면 큰일남요 :)
Posted using Partiko Android
Hi @wonsama!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your UA account score is currently 3.815 which ranks you at #4619 across all Steem accounts.
Your rank has improved 7 places in the last three days (old rank 4626).
In our last Algorithmic Curation Round, consisting of 223 contributions, your post is ranked at #138.
Evaluation of your UA score:
Feel free to join our @steem-ua Discord server