Frontend/Dart&Flutter

Dart 기초 (Functions, Classes)

괴발새발자 2023. 8. 15. 20:39

Functions

  • Defining functions
void main() {
  print(sayHelloReturn('nico')); // Hello nico nice to meet you!
  print(sayHelloArrow('nico')); // Hello nico nice to meet you!
}

// returns nothing(void)
void sayHello(String name) {
  print('Hello $name nice to meet you!');
}

String sayHelloReturn(String potato) {
  return 'Hello $potato nice to meet you!';
}

// fat arrow syntax(1 line without bracket)
String sayHelloArrow(String potato) => 'Hello $potato nice to meet you!';
num plus(num a, num b) => a + b;
  • Named Parameters
// using default value
String sayHello({
  String name = 'anon',
  int age = 99,
  String country = 'wakanda',
}) {
  return 'Hello $name, you are $age, and you come from $country';
}

// required modifier
String sayHello2({
  required String name,
  required int age,
  required String country,
}) {
  return 'Hello $name, you are $age, and you come from $country';
}

void main() {
  print(sayHello(age: 12, name: 'tomato'));
  print(sayHello(name: 'nico', country: 'germany', age: 12));
  print(sayHello2()) // Error : require name, age, country
}
  • Optional Positional Parameters
String sayHello(String name, int age, [String? country = 'cuba']) =>
    'Hello $name, you are $age years old and from $country';

void main() {
  var results = sayHello('nico', 12);
  print(results);
}
  • QQ Operator : ?? , ?=
// 예제 1 == 예제 2 == 예제 3
// 예제 1
String capitalizeName(String? name) {
  if (name != null) {
    return name.toUpperCase();
  }
  return 'ANON';
}

// 예제 2
String capitalizeName(String? name) => name != null ? name.toUpperCase() : 'ANON';

// 예제 3
// left ?? right -- left에 값이 있을 때 --> left
// left ?? right -- left에 값이 없을 때 --> right
String capitalizeName(String? name) => name?.toUpperCase() ?? 'ANON';

void main() {
  capitalizeName('nico');
  capitalizeName(null);
}
void main() {
  String? name;
  name ??= 'nico';
  name = null;
  name ??= 'another';
  print(name); // another
}

void main() {
  String? name;
  name ??= 'nico';
  name ??= 'another';
  print(name); // nico
}
  • Typedef
typedef ListOfInts = List<int>;

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

typedef UserInfo = Map<String, String>;

String sayHi(UserInfo userInfo) {
  return 'Hi ${userInfo['name']}';
}

void main() {
  print(reverseListOfNumbers([1, 2, 3])); //[3, 2, 1]
  print(sayHi({'name': 'nico'})); // Hi nico
  print(sayHi({'xyz': 'nico'})); // Hi null
}

 

Classes

  • Basic class
class Player {
  // 타입을 반드시 명시
  String name = 'nico';
  final String lastName = 'brown';
  int xp = 1500;

  void sayHello() {
    var name = 'coco';
    // don't need to use 'this' : 같은 이름의 name 변수가 있는 것이 아니라면 Player 클래스의 name을 참조함
    print('Hi my name is $name');
    print('No, my name is ${this.name}');
    print('My first last name is $lastName');
  }
}

void main() {
  var player = Player();
  // 인스턴스 생성
  print(player.name);
  player.name = 'lalala';
  print(player.name);
  player.sayHello();  
  // player.lastName = 'kim'; // 에러
}

// 결과값
// nico
// lalala
// Hi my name is coco
// No, my name is lalala
// My first last name is brown
  • Constructors
// 전형적 사용
class Player {
  late final String name;
  late int xp;

  Player(String name, int xp) {
    this.name = name;
    this.xp = xp;
  }

  void sayHello() {
    print('Hi my name is $name');
  }
}

void main() {
  var player = Player('nico', 1500);
  var player2 = Player('lynn', 2500);
  player.sayHello();
  player2.sayHello();
}

// 결과값
// Hi my name is nico
// Hi my name is lynn
// 간결한 사용
class Player {
  final String name;
  int xp;

  Player(this.name, this.xp);

  void sayHello() {
    print('Hi my name is $name');
  }
}

void main() {
  var player = Player('nico', 1500);
  var player2 = Player('lynn', 2500);
  player.sayHello();
  player2.sayHello();
}

// 결과값
// Hi my name is nico
// Hi my name is lynn
  • Named Constructor Parameters
class Player {
  final String name;
  int xp;
  String team;
  int age;

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

  void sayHello() {
    print('Hi my name is $name');
  }
}

void main() {
  var player = Player(
    name: 'nico',
    xp: 1200,
    team: 'blue',
    age: 21,
  );
  var player2 = Player(
    name: 'lynn',
    xp: 2500,
    team: 'red',
    age: 12,
  );

  player.sayHello();
  player2.sayHello();
}
  • Named Constructors
class Player {
  final String name;
  int xp, age;
  String team;

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

  Player.createBluePlayer({
    required String name,
    required int age,
  })  : this.age = age,
        this.name = name,
        this.team = 'blue',
        this.xp = 0;
  // player 클래스를 초기화

  Player.createRedPlayer(String name, int age)
      : this.age = age,
        this.name = name,
        this.team = 'red',
        this.xp = 0;
  // player 클래스를 초기화

  void sayHello() {
    print('Hi my name is $name from $team. I\\'m $age with xp $xp');
  }
}

void main() {
  var player = Player.createBluePlayer(
    name: 'nico',
    age: 21,
  );

  var redPlayer = Player.createRedPlayer('lynn', 34);

  player.sayHello();
  redPlayer.sayHello();
}
  • Named Constructor의 JSON 응용
class Player {
  final String name;
  int xp;
  String team;

  Player.fromJson(Map<String, dynamic> playerJson)
      : name = playerJson['name'],
        xp = playerJson['xp'],
        team = playerJson['team'];
        // playerJson 프로퍼티로 초기화

  void sayHello() {
    print('Hi my name is $name');
  }
}

void main() {
  var apiData = [
    {'name': 'nico', 'team': 'red', 'xp': 0},
    {'name': 'lynn', 'team': 'red', 'xp': 0},
    {'name': 'dart', '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('Hi my name is $name');
  }
}

void main() {

  // 보통 알고 있는 속성값 변경
  var nico = Player(name: 'nico', xp:1200, team: 'red')
  nico.name = 'las';
  nico.xp = 120000;
  nico.team = 'blue';

  // ..를 이용해 변수 반복 줄임
  var nico = Player(name: 'nico', xp: 1200, team: 'red');
  var potat = nico
    ..name = 'las'
    ..xp = 120000
    ..team = 'blue'
    ..sayHello(); // Hi my name is las
}
  • Enums
// option type
enum Team {red, blue}
enum XPLevel { beginner, medium, pro }

class Player {
  String name;
  XPLevel xp;
  Team team;

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

  void sayHello() {
    print('Hi I\\'m from is $team');
  }
}

void main() {
  
  var nico = Player(name: 'nico', xp:XPLevel.beginner, team: Team.red);
  var potat = nico
    ..name = 'las'
    ..xp = XPLevel.pro
    ..team = Team.blue
    ..sayHello(); // Hi I'm from is Team.blue
}
  • Abstract Classes : 인스턴스를 직접 생성하지 않고 다른 클래스들이 직접 구현해야하는 메소드들을 모아 놓은 일종의 청사진
// 추상 클래스
abstract class Human {
  void walk();
}

// 확장 클래스
class Player extends Human {
  String name;

  Player({required this.name});

  void sayHello() {
    print('Hi I\\'m $name');
  }
  // walk 메소드가 없으면 에러가 발생
  void walk() {
    print('$name is walking');
  }
}

// 확장 클래스
class Coach extends Human {
  void walk (){
    print('the coach is walking');
  }
}

void main() {
  
  var nico = Player(name: 'nico');
  nico.walk();
  var coach = Coach();
  coach.walk();
  
}

// 실행 결과
// nico is walking
// the coach is walking
  • Inheritance
class Human {
  final String name;
  Human(this.name);
  void sayHello() {
    print("Hi my name is $name");
  }
}

enum Team { blue, red }

class Player extends Human {
  final Team team;
  // super 키워드를 통해 (확장을 한) 부모 클래스와 상호작용 가능
  Player({required this.team, required String name}) : super(name);
  
  @override
  void sayHello(){
    super.sayHello();
    print('and I play for $team');
  }
}

void main() {
  var player = Player(team: Team.red, name: 'nico');
  player.sayHello();
}
  • Mixins : 생성자 없는 클래스. 클래스에 프로퍼티를 추가할 때 사용함 (예전 class 키워드 → mixin 키워드)
mixin Strong {
  final double strengthLevel = 1500.99;
}

mixin QuickRunner {
  void runQuick(){
    print('ruuuuuun!');
  }
}

mixin Tall {
  final double height = 1.99;
}

class Player with Strong, QuickRunner, Tall {
  Player({required String name});
}

void main() {
  var player = Player(name: 'nico');
  player.runQuick(); // ruuuuuun!
}