<Dart> About Dart

yezee·2023년 7월 1일
0

Flutter

목록 보기
1/15
post-thumbnail

🌟 why Dart?

  1. UI 최적화용- 사용자 인터페이스 생성 요구에 특화된 프로그래밍 언어로 개발
  2. 생산적인 개발- 핫 리로드를 사용하여 실행 중인 앱에서 즉시 결과 확인가능
  3. 모든 플랫폼에서 빠름

1.모든 플랫폼에서 빠른 앱을 위한 클라이언트 최적화 언어이다

2. dart의 컴파일러 기술을 사용하면 다양한 방식으로 코드를 실행할 수 있다

dart web dart로 쓴 코드를 js로 변환해주는 컴파일러
dart Native dart코드를 여러 cpu의 아키텍처에 맞게 변환시켜주는 컴파일러

dart는 두개의 컴파일러를 가지고 있다
JIT(just-in-time)
dart VM을 사용해서 코드의 결과를 바로 보여준다
개발중에만 사용하며 배포에는 사용하지 않는다
AOT(ahead-of-time)
컴파일을 먼저하고 그 결과인 바이너리를 배포하는 것으로 시스템에 맞게 최적화된 바이너를 생성하기 위해 컴파일에 많은 시간이 걸린다
최종 배포시 사용한다
ex) c++

🌟 use Dart

✨ Dart의 변수

main함수

main함수는 모든 dart 프로그램의 entry point이다
main함수에서 쓴 코드가 호출된다
dart는 자동으로 세미콜론을 붙여주지 않기 때문에 직접 붙여야한다( 일부러 세미콜론을 안 쓸 때가 있기 때문)

void main(){
print("hello world");
}

변수를 만드는 2가지 방법

함수나 메소드 내부에 지역변수를 선언할 때는 var을 사용하고
class에서 변수나 property를 선언할 때는 타입을 지정해준다
데이터 타입이 일치하다면 변수는 업데이트 가능하다

void main(){
var name="pizza"; //방법1
String name="Chicken"; // 방법2
//방법1과 방법2는 같은 것
}

상수를 만드는 방법

  • final
    var대신 final로 변수를 만들게 되면 이 변수는 수정할 수 없게 된다
    자바스크립트의 const랑 비슷하다
void main(){
final name="nico"
name="yeji" //로 수정불가능하다->에러발생
}
  • const
    Dart에도 const라는 변수가 존재한다. 하지만 지금까지 js에서 배운 const는 final과 더 유사하다
    Dart에서의 const는 compile-time constant를 만들어준다.

const: 컴파일 시점에 바뀌지 않는 값 (상수)
final: 컴파일 시점에 바뀌는 값, 런타임 중에 만들어질 수 있는 변수 (API에서 받아온 값, 사용자 입력값)

late 변수

초기 데이터 없이 먼저 변수를 생성하고 추후에 데이터를 넣을 때 주로 사용한다.
flutter로 data fecthing을 할 때 유용하다.
late 변수를 만들고, API에 요청을 보낸 뒤에 API에서 값을 보내주면 그 응답값을 late변수에 넣어 사용할 수 있다.

void main() {
late final name;

print(name); // name 변수에 접근 불가
}

Dynamic 타입

여러가지 타입을 가질 수 있는 변수에 쓰는 키워드이다(해당 변수의 타입을 알 수 없을 때 주로 사용)
변수를 선언할때 dynamic을 쓰거나 값을 지정하지 않으면 dynamic타입을 가진다

void main(){
var name //방법1
dynamic name // 방법2
//방법1과 방법2는 같은 것
}

null safety

null값을 참조할 수 없도록 하는 것
변수선언 뒤에 ?를 붙여줌으로서 name이 string 또는 null이 될 수 있다고 명시해주는 것
기본적으로 모든 변수는 non-nullable(null이 될 수 없음)이다

void main() {
String? name = "hello";
name = null;
}

✨ Dart의 데이터타입

자료형

dart의 거의 대부분의 타입들이 객체로 이루어져있다
String, int, double, bool 모두 class이다
따라서 import할 필요 없이 해당 자료형이 가지는 모든 method를 사용할 수 있다

void main(){
String name = "tom";
bool isPlay = true;
int age = 10;
double money = 52.55;
num x = 12;  //num은 그 값이 integer 일 수도 있고 double 일 수도 있다.
num y = 1.2;

}

Lists

dart에서 list를 선언하는 것에 두가지 방법이 있다

void main(){
var num=[1,2,3];
List num=[1,2,3];
}

dart의 유용한 점은 collection ifcollection for을 지원한다

  • collection if
    List를 만들 때, if를 통해 존재할 수도 안할수도 있는 요소를 가지고 만들 수 있다
    쉽게말해 배열안에 조건문을 만들수있다!
    void main() {
     var giveMeFive = true;
     List num = [1, 2, 3, 4, if (giveMeFive) 5];  //giveMeFive가 true면 5추가
     print(num); //[1, 2, 3, 4, 5]
    }
  • collection for
    void main() {
    var oldFriends = ["nico", "lynn"];
    var newFriends = [
    "tom",
    "jon",
    for (var friend in oldFriends) "❤️ $friend"
    ];
    print(newFriends); // [tom, jon, ❤️ nico, ❤️ lynn]
    }

변수 사용하는 방법

$달러 기호를 붙이고 사용할 변수를 적어주면 된다.
만약 계산을 싱행하고 싶다면 ${ } 형태로 적어주면 된다.

void main() {
  var name = "yeji";
  var age = 10;
  var greeting = "Hello everyone, my name is $name and I'm ${age + 2}";
}

maps

key와 value를 연결하는 객체
키와 값 모두 모든 유형의 객체가 될 수 있다

void main() {
  var player={
  "name":"nico",
  "xp":19.99,
  "superpower":false
  } //방법1
  
  Map player={
    "name":"nico",
  "xp":19.99,
  "superpower":false
  } //방법2
  
}

Sets

set에 속한 모든 아이템들이 유니크해야될 때 사용한다
유니크할 필요가 없다면 list를 사용하면 된다
왜냐하면, list는 같은 요소가 여러개 반복될 수 있지만, set은 중복이 허용되지 않는다

void main() {
  var numbers={1,2,3,4}; // 방법1. var을 사용
  Set<int> numbers={1,2,3,4}; //방법2.자료형 명시
}

set에는 순서가 있다
print({1,2,3}=={3,2,1});을 해보면 false가 나타난다

map

void main(){
 var numbers=[1,2,3,4]
 numbers.add(1)
 numbers.add(1)
 print(numbers) //1,2,3,4,1,1
}

set

void main(){
 var numbers={1,2,3,4}
 numbers.add(1)
 numbers.add(1)
 print(numbers) //1,2,3,4
}

✨ Dart의 함수

dart는 진정한 객체지향언어이므로 함수도 객체이며 타입이 Function입니다
이는 함수를 변수에 할당하거나 다른 함수에 인수로 전달 할 수 있음을 의미합니다

//하나의 표현식만 포함하는 함수의 경우 아래와 같이 단축 구문을 사용할 수 있다
String sayHello(String name)=> "Hello  ${name} nice to meet you";

void main(){
print(sayHello("yeji")); //Hello yeji nice to meet you"
}

void 함수가 아무것도 return하지 않는다는 의미

named parameters

명시적으로 required로 표시되지 않는 한 선택사항
기본값을 제공하지 않거나 Named parameters를 필수로 표시하지 않으면 해당 유형은 기본값이 null이 되므로 null을 허용해야합니다
named parameter로 만들어주기 위해서는 함수의 파라미터를 중괄호로 감싸주면 된다
하지만 null-safety가 적용되어있기 때문에 default value를 지정해주거나 required키워드를 통해 반드시 값을 받도록 해주어야한다

String sayHello({String name = "yeji", int age = 20, String country = "ko"}) =>
    "hello $name, you are $age, and you come from $country";

void main() {
  print(sayHello(
    name: "yeji",
    country: "japan",
    age: 27,
  ));
}

required을 사용하면 null safety를 적용할 수 있다.(required를 쓰면 값이 반드시 있어야 한다.)

String sayHello({ 
//디폴트 velue를 사용하는 방법
  required String name,
  required int age,
  required String country
})=> "hello $name, you are $age, and you come from $country";


void main() {
    print(sayHello(
    name: "yeji",
    country: "japan",
    age: 27,
  ));
}

optinal positional parameters

dart에서 []는 optional parameter를 명시할때 사용

String sayHello(
String name,
int age,
[String? country = "korea"],
) => return "Hello $name, age: $age, country $country";

void main(){
print(sayHello(
name: "jisoung",
age: 17,
);
}

QQ operator

??연산자를 이용하면 null인지 체크해서 null이 아니면 왼쪽값을 리턴하고 null이면 오른쪽 값을 리턴한다

String capitalizeName(String?name)=>name?.toUpperCase() ?? "ANON" 

??= 연산자를 이용하면 변수안에 값이 null일때를 체크해서 값을 할당해줄 수 있다

void main() {
String? name;
name ??= "sugar"; //name이 null일때, sugar를 값으로 할당해준다
}

TypeDef

자료형에 사용자가 원하는 alias(자료형 이름의 별명을 만들때 사용)를 붙일 수 있게 해준다

typedef ListOfInts = List<int>;

ListOfInts reverseListOfNumbers(ListOfInts list) {
var reversedList = list.reversed.toList();
return reversedList;
}

✨ Dart의 Class

class를 생성할 때는 타입을 명시해주어야한다

class Player {
  String name = "nico";
  int xp = 1500;

  void sayHello() {
    var name = "yeji";
    print("hi! my name is $name"); // hi my name is yeji  
    print("hi my name is ${this.name}"); //hi my name is nico
  }
}

void main() {
  var player = Player(); //Player()를 호출하면 Player인스턴스가 생성된다
  player.sayHello();
}

class내부 함수에서는 this로 변수값을 가져오지 않는다.
단, 함수내부에 같은 이름의 변수명이 있다면 this를 통해 명시해줘야한다

constructors

Named Constructor parameters

class Player {
  String name;
  int xp;
  String team;
  int age;

  Player(
      {required this.name,
      required this.xp,
      required this.team,
      required this.age}); //constructors 생성방법

  void sayHello() {
    print("hi, my name is $name and i am $xp");
  }
}

void main() {
  var player = Player(name: "yeji", xp: 1300, team: "blue", age: 17);
  var player2 = Player(name: "rak", xp: 1600, team: "pink", age: 21);

  player.sayHello();
  player2.sayHello();
}

생성자(constructor)함수를 여러개 만들고 싶다면 어떨까?
콜론(:)을 사용하면 특별한 생성자 함수를 만들 수 있다
콘론을 넣음으로서 dart에게 여기서 객체를 초기화하라고 명령할 수 있다

class Player {
  final String name;
  int xp;
  String team;

  Player.fromJson(Map<String, dynamic> playerJson)
      : name = playerJson["name"],
        xp = playerJson["xp"],
        team = playerJson["team"];

  void sayHello() {
    print("hello my name is $name");
  }
}

void main() {
  var apiData = [
    {
      "name": "yeji",
      "team": "red",
      "xp": 0,
    },
    {
      "name": "rak",
      "team": "red",
      "xp": 0,
    },
    {
      "name": "nico",
      "team": "red",
      "xp": 0,
    }
  ];

  apiData.forEach((playerJson) {
    var player = Player.fromJson(playerJson);
    player.sayHello();
  });
}

cascade Notation

class Player {
  String name;
  int xp;
  String team;

  Player({required this.name, required this.xp, required this.team});

  void sayHello() {
    print("hello my name is $name");
  }
}

void main() {
  var yeji = Player(name: "yeji", xp: 1200, team: "red")
    ..name = "las" //...은 yeji.name와 같다
    ..xp = 1200000 //...은 yeji.xp와 같다
    ..team = "blue" ////...은 yeji.team과 같다
    ..sayHello(); // hello my name is las
}

Enums

enum은 우리가 실수하지 않도록 도와주는 타입이다

enum Team{red, blue}
enum XPLevel{beginner,medium, pro}

class Player {
  Team team;
  XPLevel xp

  Player({required this.team, required this.xp});
}

void main() {
  var yeji = Player(team: Team.red);  //enum을 사용해서 실수를 줄이는 방법
}

Abstract class

추성화 클래스는 이를 상속받는 모든 클래스가 가지고있어야 하는 메소드를 정의하고 있다
추상화 클래스에서는 기능을 구현하지 않는다
extends를 이용해 상속,확장을 할 수 있다

abstract class Human {
  void walk();
}

class Player extends Human {
  void walk() {
    print("im walking");
  }
}

class Coach extends Human {
  void walk() {
    print("the coach is walking");
  }
}

interitance

super라는 키워드를 통해 확장을 한 부모클래스와 상호작용할 수 있게 해준다
즉, 상속한 부모 클래스의 프로퍼티에 접근하게 하거나 메소드를 호출할 수 있게 해준다
@override를 이용해 부모 클래스의 객체를 받아올 수 있다.

class Human {
final String name;
Human(this.name); // 호출 받는다.
void sayHello(){
print("Hello! $name");
}
}

class Player extends Human {
Player({
required this.team,
required String name
}) : super(name: name);
// super를 통해 부모클래스와 상호작용할 수 있게해준다


void sayHello(){
super.sayHello(); //Human의 print("Hello! $name")을 불러온다
}
}

Mixins

Mixin은 생성자가 없는 클래스를 의미한다
Mixin클래스는 상속을 할때 extend를 하지 않고 with를 사용한다
Mixin의 핵심은 여러 클래스에 재사용이 가능하다

mixin과 extends의 차이점은요??
extends를 하게되면 확장한 그 클래스는 부모 클래스가 되지만 with는 부모의 인스턴스 관계가 된다
단순히 mixin 내부의 프로퍼티를 갖고 오는것

mixin Strong {
  final double strength = 1500.0;
}

mixin QuickRunner {
  void runQuick() {
    print("runnnnn!");
  }
}

enum Team { blue, red }

class Player with Strong, QuickRunner {
  final Team team;

  Player({required this.team});
}

void main() {
  var player = Player(team: Team.red);
}
profile
아 그거 뭐였지?

0개의 댓글