====== dart 언어 ======
https://dartpad.dev/
===== 일반 =====
void main() {
for (int i = 0; i < 5; i++) {
print('hello ${i + 1}');
}
// type
String, double, int, bool, var
print ( name + ' ' + name2);
print ('$name $name2'); // 변수만 쓰면 {} 없어도 됨
print ('${number+1} ${name2}');
// var, dynamic
print (name.runtimeType);
//var : 한번 선언하면 fix
// dynamic : type 바뀔 수 있음
// nullable, non-nullable
String? name = 'asd'; // ? 끝에 붙이면
name = null; //가능
print(name2!); // !현재 이값은 null이 아니다 (null 안들어가는 함수쓸 때)
final String name = 'asdf'; // name 바꿀 수 없음
const String name2 = 'asdf'; // 비슷
final name = 'sdaf'; // type 생략 가능
const name2 = 'sadf'; // type 생략 가능
// 차이
// final : build time
final DateTime now = DateTime.now(); //build time 몰라도 됨
// const 는 안됨 : build time 알고 있어야 함 (절대적으로)
// % : 나머지
number ++; // +1 하면서 변경 ex. --;
number += 2; // +2 하면서 변경 ex. *=, /=
number ??= 3; // number가 null이면 3 (아니면 안바뀜)
// == 같은지, != 다른지
// type비교
print (number1 is int);
print (number1 is! String);
bool result = 12 > 10 && 1 > 0; // || : or
// List
List lst = ['1','2','3']; // List numbers = [1,2,3];
lst[0]; lst.length; lst.add('4'); lst.remove('3'); lst.indexOf('4');
// Map : Key/Value
Map dictionary = { 'a' : '1', 'b' : '2', };
dictionary.addAll( { ~~~ } );
dictionary['a'];
dictionary['c'] = '3'; dictionary['c'] = '4'; //변경
dictionary.remove('a'); dictionary.keys; dictionary.values;
// Set : 중복없는 list
final Set names = { 'a','b','c', 'c' };
names.add('d'); names.remove('a');
names.contains('d');
if (조건) { } else if ( 조건 ) { } else { }
switch ( number % 3 ) {
case 0:
print('sadf');
break; //넣어줘야 함
case 1:
...
default:
print('sdf');
break;
}
for ( int i = 0; i < 10; i++) { }
for ( int number in numbers ) { } // numbers list에 있는 값들
while ( 조건 ) { }
do { } while ( ); //먼저 do 하고 (거의 안씀)
// break; // continue;
}
// enum : 함수 밖에 선언
enum Status { approved, pending, rejected, } // 함수 밖에 선언
//사용할 때
Status status = Status.pending;
if (status == Status.approved ) { .... }
// 정확히 이 세개 밖에 없다는 것을 알려줌, 오타 방지
///////////////////////////////////////////////////////////////////////////////////////
//// 함수
///////////////////////////////////////////////////////////////////////////////////////
// positional parameter
addNumbers(int x, [int y=20, int z=30]) { } // [ Optional ], null이 된다면 [int? y, int? z] // 없으면 void와 동일
// named parameter
addNumbers({ required int x, required int y, required int z } ) { } // addNumbers(y:10, x:20, z:30 ) // 순서 바뀌고 이름 넣어야 함
addNumbers({ required int x, required int y, int z=30 } ) { } // required 없애면 optional이 됨
int addNumbers ( ) { return x; }
// arrow function
int addNumbers( int x, {required int y, int z = 30,} ) => x+y+z;
// typedef : 함수 밖에 선언
typedef Operation = int Function(int x, int y, int z); //
int add(int x, int y, int z) => x+y+z;
int substract(int x, int y, int z) => x-y-z;
// 사용할 때1
Operation operation = add; // add라는 함수로 정의
int result = operation(10,20,30);
// 사용할 때2
int calculate(int x, int y, int z, Operation operation) {
return operation(x,y,z);
}}
int result2 = calculate(30,40,50,add);
///////////////////////////////////////////////////////////////////////////////////////
//// CLASS
///////////////////////////////////////////////////////////////////////////////////////
void main() {
//Idol blackpink = Idol(); // new Idol(); 같음
//Idol blackpink = Idol('블랙핑크', ['a','b','c']); // new Idol(); 같음
print(blackpink.name);
blackpink.sayhello();
}
// Idol class
class Idol { // _Idol (constructor 이름도 바꿔주면) : private 속성 : 다른파일에서 import 해도 못씀
final String name;
final List members; // 웬만하면 final 로 선언해야 함 : immutable programming
// CONSTRUCTOR 사용법
// 1. constructor
Idol(String name, List members)
: this.name = name;
this.members = members;
// 2.
// Idol(this.name, this.members); //로 하면 더 간단함
// const Idol(this.name, this.members); 로 하면 좋음? //const constructor : (변수들이 final일 때)
// -> 사용할 때 Idol blackpink = const Idol('A', ['a'] );
// Idol blankpink2 = const Idol('A', ['a'] ); // 일 때,(똑같은 변수) const 이면 blackpink == blankpink2 는 true, 아니면 false
// 3. named constructor
Idol.fromList(List values)
: this.members = values[0],
this.name = values[1];
// 1or2 와 공존 가능하고,
// instance 선언할 때
// Idol bts = Idol.fromList ( [ ['a','b','c'], 'BTS' ] ); // 로 사용 가능
void sayHello() {
print('안녕하세요 ${this.name} 입니다.'); // method 안에 name 없으면 this. 없어도 됨
}
void introduce() {
print('저희 멤버는 ${this.members}가 있습니다');
}
// getter
String get firstMember { // () 없음
return this.members[0];
} // 사용 : blackpink.firstMember
// setter
set firstMember(String name) { //무조건 한개 parameter
this.members[0] = name;
} // final, const 없어야 함
// 사용 : blackpink.firstMember = '아이언맨'
// final (immutable programming) 때문에 setter는 잘 안씀
//static은 instance에 귀속되지 않고, class에 귀속된다
static String? building; // Idol.building = '하이브타워'; // 클래스에 direct로, instance끼리 공통
static void printBuilding() { } // static method
}
// 상속 (inheritace)
// BoyGroup은 Idol type 도 됨 : is Idol = true
class BoyGroup extends Idol { //extends
BoyGroup ( String name, int membersCount, ) :
super(name : name, membersCount : membersCount); //constructor : super
void sayMale() {
print("나는 남자");
}
// method - class 내부에 있는 함수
// override
@override // @override 써주면 직관적임 (없어도 됨)
void method_of_parent() {
return super.method_of_parent() ~~~; //super 부모 method 그대로 가져오기
}
}
// interface : 클래스에 필수적인 template
abstract class Idolinterface() {
//abstract : instance로 만들 수 없음 (설계로만 쓸거임)
String name;
IdolInterface(this.name);
void sayName() {}
}
class BoyGorup implements Idolinterface{
//인터페이스와 동일한 구조로 만들어야 함
}
// generic : 타입을 변수처럼 외부에서 받을 때
// ex. List : List를 String으로
class Lecture { // 여러개 넣을 수 있음
final T id;
final String name;
Lecture(this.id, this.name);
}
// Lecture lec1 = Lecture('123','lec1');
// OOP : 모든 클래스는 extends Objects() 하고 있음
///////////////////////////////////////////////////////////////////////
//Functional Programming : (중요 : 새로운 객체로 나옴!)
///////////////////////////////////////////////////////////////////////
// 코드 간결
// 형변환
List b = ['a',...,'d'];
b.asMap();
b.toSet();
Map c = b.asMap();
c.keys; // () : Iterable<> -> List로 바꿔줘야 함
c.keys.toList();
// map : 새로운 list가 나옴 ( b == new_b : false )
final new_b = b.map((x) { // list의 각각 원소가 x로 들어감
return '블랙핑크 $x';
} );
new_b.toList(); //Iterable 로 나오니까
//arrow 로 간편하게
final new_b2 = b.map( (x) => '블랙핑크 $x' );
// map 예시
String number = '13579';
final parsed = number.split('').map( (x) => '$x.jpg').toList(); // [1.jpg, 2.jpg, ...]
//MAP 형인 경우
final result = new_b.map( (key,value) => MapEntry( 'asdf $key', '123 $value',) );
final keys = new_b.keys.map( (x) => 'sdf $x').toList();
//Set형 인경우
newSet = b.map( (x) => ... ).toSet();
// Where
List< Map > people = [ {'name': ~~, 'group': '~~~'}, {~~~} ]; // List 안에 Map
final blackpink_p = people.where( (x) => x['group'] == '블랙핑크' ).toList(); //맞는것만 남김
//Reduce
List numbers = [1,3,5,7,9];
final result = numbers.reduce( (prev,next) {
print('----');
print('prev : $prev');
print('next : $next');
return prev+next;
} );
//(1+3) -> 4 // + 5 -> 9 // + 7 = 16...
final result = numbers.reduce( (prev,next) => prev + next );
List words = ['a','b','c'];
final sentence = words.reduce( (prev,next) => prev + next );
//Fold : return이 같은 형이 아니어도 됨
final sum = numbers.fold( 0, (prev,next) => prev + next ); // 0 + 1 = 1 // + 3
final sentence = words.fold( '', (prev,next) => prev + next );
final count = words.fold( 0, (prev,next) => prev + next.length ); //글자들의 길이
// cascading operator
List even = [2,4,6,8];
List odd = [1,3,5,7];
print( [...even, ...odd]); // ... 하면 List 없어지고, 원소들이 나옴 (원래는 [[...], [...]] )
// 예시
// 원래 Map은 name, group 말고 다른 이름이든 다른 추가 내용이든 있을 수 있음 (자유도 높음)
// Json 등으로 들어온 데이터를 class 로 유효성 검사?
List< Map > people = [ {'name': ~~, 'group': '~~~'}, {~~~} ]; // List 안에 Map
final parsedPeople = people.map ( (x) => Person ( name: x['name']!, group: x['group']!, ) ).toList(); // !로 무조건 존재한다 표현
print(parsedPeople); // toString override한 걸로 string 으로 바뀌어서 출력됨 (원래는 'instance of Person' 으로 출력됨 )
// 아래 처럼 data 유효성 검사 없이 활용 가능함
for (Person person in parsedPeople) {
print(person.name);
print(person.group);
}
final bts = parsedPeople.where( (x) => x.group == 'BTS');
class Person {
final String name;
final String group;
Person( {
required this.name, required this.group, } );
@override
String toString() {
return 'Person(name:$name, group:$group)';
}
}
///////////////////////////////////////////////////////////////////////
////Asynchronous Programming
///////////////////////////////////////////////////////////////////////
// CPU Thread : 실행 단위 (실행 중에는 사용 불가)
// 서버요청 예시 : Network 요청을 위해서 돌아올 때까지 CPU가 막혀버림 (사용하지 않음에도) : synchronous programming
// CPU 효율적으로 사용하는 방법
//Future
//Future name = Future.value('코드팩토리'); //미래에서 받아올 값
// delayed - 2개의 파라미터 : 지연할 기간 Duration, 지연 지난 후 실행할 함수
Future.delayed( Duration(seconds: 2), () { print('Delay 끝'); } );
//예시
void addNum(int n1, int n2) {
print (' 시작 ' );
//서버시뮬레이션
Future.delayed( Duration(seconds:2), () {
print(' 계산완료');
});
print ('함수완료');
}
addNum(1,1); //실행하면 : 시작->함수완료->계산완료 (Future 없으면 시작->계산완료->함수완료)
//CPU 쉬고 있는 순간 다른 것 먼저 실행
//await : 실제로 논리적으로 기다리긴 함
//함수완료에서 await 결과가 필요할 때
void addNum(int n1, int n2) async { //async 필요함
print (' 시작 ' );
//서버시뮬레이션
await Future.delayed( Duration(seconds:2), () { //await
print(' 계산완료');
});
print ('함수완료');
}
//하지만 CPU는 다른 작업하기는 함
addNum(1,1);
addNum(2,2); // 계산시작(1,1) - 계산시작(2,2) - (계산완료 - 함수완료)(1,1) - (계산완료 - 함수완료)(2,2)
// 1,1 2,2 순서대로 하고 싶을 때
void main() async{
await addNum(1,1);
await addNum(2,2);
}
//await은 Futre가 return되는 것만 됨
Future addNum(....) { }
// 받아서 사용
void main() async{
Future result1 = await addNum(1,1);
Future result2 = await addNum(2,2);
print( result1+result2);
}
//Stream
// Futre : 실행 -(await)->완료-반환 (1개)
// Stream : 실행 -(yield-반환값1)-(yield-반환값2) -... -> 완료
import 'dart:async'; // 잘 안씀 : open src pkg 가 있으니까 이런 raw lib 쓸일은 없음
final controller = StreamController();
final stream = controller.stream.asBroadcastStream(); //as~ : 2번이상 listener하려면 필요
//1은 짝수만, 2는 홀수만
final streamListener1 = stream.where( (val) => val % 2 == 0).listen( (val) {
print('Listener 1: $val');
});
final streamListener2 = stream.where( (val) => val % 2 == 1).listen( (val) {
print('Listener 2: $val');
});
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
controller.sink.add(4);
controller.sink.add(5);
// 예시
void main(){
// 1초씩 동시에 실행됨
cal(2).listen( (val) {
print (' $val');
});
cal(4).listen( (val) {
print (' $val');
});
}
Stream cal(int num) async* {
for (int i=0; i<5; i++ ) {
//return i*num; //return 이면 0만 return 되고 끝나버림
yield i*num; //cal 함수를 listening하는 stream에 값을 뿌려줄 수 있음
await Future.delayed( Duration(seconds: 1)); // 1초씩 계산되어 나옴
}
}
// 순서대로 실행
playAllStream.listen( (val) { print(val); });
Stream playAllStream() async* {
yield* cal(1); // * : 모든 값이 나올 때까지 기다림
yield* cal(1000);
}
===== 날짜, Duration ====
DateTime now = DateTime.now();
now
now.year
now.month
now.day
now.hour
now.minute
now.second
now.millisecond
Duration duration = Duration(seconds: 60);
duration
duration.inDays
duration.inHours
duration.inMinutes
duration.inSeconds
duration.inMilliseconds
DateTime sepcificDay = DateTime(
2023,11,23, //위 순서대로
);
final diff = now.difference(specificDay);
diff.inDays // ....
now.isAfter(specificDay)
now.isBefore(specificDay)
now.add(Duration(hours:10))
now.substract(Duration(seconds:20))
{{tag>sotfware_development dart language}}
~~DISCUSSION~~