link: dartpad.dev 로 가면 바로 dart 언어를 사용할 수 있는 tool이 제공되는 웹사이트로 갈 수 있음
void main() {
for (int i = 0; i < 5; i++) {
print('hello ${i + 1}');
}
}
// 메인 함수를 호출해서 run 하기 때문에 main 함수가 있어야 함
// 세미콜론을 꼭 달아줘야 함. 왜냐하면 필요에 따라 세미콜론을 안 쓸 수도 있기 때문
void main() {
var name = 'abc'; // type을 추출함
// name 에는 이미 스트링 문자열을 넣어주었기 때문에 값을 업데이트 할 수는 있지만 문자열로만 업데이트가 가능함
// 즉, 정수, bloo 등과 같은 다른 타입을 넣을 때는 업데이트가 불가능함
// 관습적으로 함수나 메소드 내부에서 지역 변수를 선언할 대는 var를 사용
// var를 사용하는 편
String name2 = 'abc';
// var 대신 명시적으로 타입을 정해줄 수 있음
// class에서 변수나 property를 선언할 때 타입 지정
}
Dynamic: 타입을 지정하지 않는 형식 -> 굉장히 유용하지만 그만큼 위험할 수 있기 때문에 꼭 필요할 때만 사용하는 것을 지향
void main() {
// dynamic: 여러가지 타입을 가질 수 있는 변수에 쓰는 키워드
// 그만큼 유용하지만 정말 필요할 때만 사용해야 함 !! 주의 !!
var name; // var로 변수를 선언하고 값을 초기화해주지 않으면 이 때 타입은 dynamic
dynamic name2; // dynamic으로 선언 가능
if (name is String){
// 이 내부 조건문에서는 named이 String 이어야만 들어올 수 있음
// 따라서 name은 String이 됨
// name.을 치고 호출 가능한 함수 리스트를 확인할 수 있음
}
name = 'jh';
name = 12;
name = true;
}
void main() {
// null safety
// dart에서는 어떤 변수가 null이 될 수 있음을 정확히 표시해야 함
String jh = 'jh';
// jh = null; // 이거는 String 형 변수에 null로 업데이트하는 것이기 때문에 불가능
// null 값을 허용하려면 타입 뒤에 ? 만 붙여주면 됨
String? jh2 = 'jh';
jh2 = null; // jh2.length를 사용할 수 있으나 null 값이 들어갈 수도 있음
if (jh2 != null){ // null 값이 아닐 경우 처리할 수 있는 조건문을 달 수 있게 됨(null safety)
jh2.isNotEmpty;
}
// 조건문을 사용할 경우 시간 효율이 떨어짐 따라서 ?를 사용하여 값의 존재 여부 체크 후 연산 진행
jh2?.isNotEmpty; // jh2가 null이 아니라면 isNotEmpty 속성을 달라고 요청하는 것
}
void main() {
final name = 'jh';
// final은 var과 다르게 변수의 값을 수정할 수 없음
// javascript, typescript의 const와 같음
}
void main() {
late final String name;
// late는 초기 데이터 없이 변수 선언을 가능하도록 도와줌
// API 요청으로 데이터를 받은 후 name에 나중에 데이터를 넣어줌
// final은 수정 금, var만 수정 가능
// late는 값이 할당되기 전까지 값을 가져올 수 없도록 제한함 -> 실수 방지
}
void main() {
// compile-time constant
const name = 'jh';
// const는 값을 수정하지 못한다.
// 가장 중요한 것은 const는 compile-time에 알고 있는 값이어야 한다.
// const API = '121212'; -> API 키를 하드코딩한 것이기 때문에 컴파일 타임에 알고 있음
// const API = featchApi(); -> API에서 받아와야 하기 때문에 컴파일러는 API 변수의 값을 모름 -> 이 경우에는 final이어야 함
// 앱에서 사용되는 상수들에는 const 사용
}
void main() {
// var: 여러 번 값을 수정할 수 있는 var, type 지정
int i = 12;
var name = 'jh';
// 위 형식은 타입을 지키면서 무한하게 수정 가능
// dart 스타일 가이드에서는 'var'를 사용하도록 권장
// final: 값을 수정하지 못하도록 하는 final
final k = 12;
// dynamic: 형식을 지정해주지 않고 나중에 지정 -> 값이 나중에 들어온다(조심히 사용할 것)
// dynamic과 조건문(if dynamic 변수에 값이 들어왔다면)은 함께 사용하는 습관
dynamic j;
// const: 컴파일 할 때 알고있어야 하는 값 (ex. API key) -> 수정 불가
const api_key = '121212';
// null safety: 잘못된 상태의 변수 참조 방지 -> null 참조 불가
String? isnull_ = 'ss';
isnull_?.isEmpty;
// late: 아직 어떤 데이터가 들어올지 모름 -> API로 값을 받아올 때 효과적
late final String name_;
}
void main() {
String name = 'jh';
bool alive = true;
int age = 25;
double money = 67.99;
num x = 12;
}
void main() {
var giveMeFive = true;
var numbers = [1,
2,
3,
4,
if (giveMeFive) 5]; // collection if
print(numbers);
List<int> nums = [1,2,3,4,];
// int 형 list에는 반드시 int 형 값만 들어가야 함
numbers.add(1);
numbers.last; // 마지막 원소 값이 궁금할 때
}
void main() {
var jh = 'jh';
var age = 10;
var greeting = "Hello everyone, my name is $jh, and I'm ${age+2}";
print(greeting);
// 단순히 호출: $기호 뒤에는 반드시 변수를 넣어주면 됨 -> $jh
// 연산을 원한다면 %{}에서 계산 진행 -> ${age+2}
}
void main() {
var oldFriends = ['nico','lynn'];
var newFriends = [
'lweis',
'ralph',
'darren',
for(var friend in oldFriends) "💖 $friend"
];
print(newFriends);
}
void main() {
var player = {
'name':'jh',
'xp': 19.99,
'superpower':true
}; // python의 딕셔너리
Map<int, bool> players = {
1: true,
2: false,
3:true
};
Map<List<int>, bool> players_ = {
[1,2,3,4]:true,
};
List<Map<String, Object>> players2 = [
{'name':'jskdf', 'xp':1212},
{'name':'sdf', 'xp':123123},
];
}
void main() {
var numbers = {1,2,3,4};
Set<int> nums = {1,2,3,4,};
numbers.add(1);
print(numbers);
}
String sayHello(String name){ // void: 아무것도 return 하지 않는다.
return ("Hello $name nice to meet you");
}
String oneline(String name) => '❤️ $name'; // 함수가 한 줄이면 return을 => 표현할 수 있음.
num plus(num a, num b) => a+b;
void main() {
print(sayHello('jh'));
print(oneline('jh'));
}
String sayHello({required String name,
required int age,
required String country}){
return 'Hello, $name you are $age, and you com from $country';
}
// parameter 부분을 중괄호로 묶어주는 것이 named parameters
// null safety가 적용되기 때문에 미리 파라미터 값을 설정해줌
void main(){
print(sayHello(
name: 'jh',
age: 24,
country:'KR',
));
// named argument: 파라미터의 순서 상관없이 호출할 수 있는 방법
// print(sayHello());
// null safety 때문에 미리 값을 초기화해주었기 때문에 값이 들어가지 않아도 괜찮음(defaut value가 정해졌다면)
// 파라미터 앞에 required가 붙으면 필수적인 값이기 때문에 빈 값으로 넣을 수 없음
}
// positional parameters
String sayHello(String name, String country, int age){
return 'Hello $name, you are $age, and you come from $country';
}
// named parameters + default value
String sayHello2({String name='aa', String country='kr', int age=99}){
return 'Hello $name, you are $age, and you come from $country';
}
// named parameters + required
String sayHello3({required String name,
required String country,
required int age}){
return 'Hello $name, you are $age, and you come from $country';
}
void main(){
// positional parameters 호출
sayHello('jh', 'kr', 99);
// named parameters 호출 + default value 설정
sayHello2(
name: 'jh',
age: 99,
country: 'kr');
// named parameters 호출 + required
sayHello3(
name: 'jh',
age: 99,
country: 'kr');
}
String sayHello(String name,
int age,
[String? country='kr']) => // country는 null이 될 수 있다.
"Hellow $name, you are $age, you com from $country";
void main(){
var results = sayHello('jh',99);
print(results);
}
String capitalizeName(String? name){ // name의 문자를 대문자로 수정하는 함수, null이 들어올 경우를 조건문으로 처리
if (name != null){
return name.toUpperCase();
}
return 'ANON';
}
String capitalizeName_2(String? name)
=> name!= null ? name.toUpperCase() : 'ANON';
// QQ operator 사용
// left ?? right
// left 항이 true 이면 left 항 진행하고 left 항이 false면 right 항 진행
String capitalizename_3(String? name)
=> name?.toUpperCase() ?? 'ANON';
void main(){
capitalizeName('jh');
capitalizeName(null);
capitalizeName_2('jh');
}
void main(){
String? name;
name ??= 'jh';
print(name);
}
typedef ListOfInts = List<int>; // 자료형 정의
typedef UserInfo = Map<String, String>;
String sayHi(Map<String, String> userInfo){
return "Hi ${userInfo['name']}";
}
ListOfInts reversListOfNumbers(ListOfInts list){
var reversed = list.reversed;
return reversed.toList(); // list로 변환
}
void main(){
print(reversListOfNumbers([1,2,3]));
print(sayHi({"name":'jh'}));
}
class Player{ // class 내부에서는 타입 명시
final String name = 'jh';
int xp = 1500;
void sayHello(){
var name = 'abc';
print('Hi my name is $name'); // name이 중복이 없다면 이대로 사용 가능하지만
print("Hi ny name is ${this.name}"); // 중복되면 this를 추가해야 함
}
}
void main(){
var player = Player(); // 인스턴스 하나 생성
print(player.name);
// player.name = 'sdf'; // final이 없을 때만 수정 가능
player.sayHello();
}
class Player{ // class 내부에서는 타입 명시
late final String name;
late int xp;
Player(String name, int xp){ // constructor method 이름은 class 이름과 같아야 함
this.name = name;
this.xp = xp;
}
void sayHello(){
print("Hi ny name is ${name}"); // 중복되면 this를 추가해야 함
}
}
// 조금 더 코드를 깔끔하게 정리
class Player2{ // class 내부에서는 타입 명시
final String name;
int xp;
Player2(this.name, this.xp);
void sayHello(){
print("Hi ny name is $name"); // 중복되면 this를 추가해야 함
}
}
void main() {
var player = Player('jh',1234); // 인스턴스 하나 생성
player.sayHello();
var player2 = Player('lynn', 12123);
player2.sayHello();
}
class Player{
// 1. type 선언
final String name;
int xp;
String team;
int age;
// 2. constructor
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:'blue',
age:12,
);
}
class Player{
// 1. type 선언
final String name;
int xp, age ;
String team;
// 2. constructor
Player({required this.name,
required this.xp,
required this.team,
required this.age});
void sayHello(){
print("Hi my name is $name");
}
Player.createBluePlayer({required String name,
required int age}): // :은 player 클래스를 초기화하는 일
this.age = age,
this.name = name,
this.team = 'blue',
this.xp = 0;
Player.createRedPlayer({required String name,
required int age}):
this.age = age,
this.name = name,
this.team = 'red',
this.xp = 0;
}
void main(){
var player = Player.createBluePlayer(
name:'nico',
age:21,
);
var redplayer = Player.createRedPlayer(
name:'lynn',
age:12,
);
}
class Player{
// 1. type 선언
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("Hi my name is $name");
}
}
void main(){
var apiData = [
{
'name':'nico',
'team':'red',
'xp':0,
},
{
'name':'lynn',
'team':'red',
'xp':0,
},
{
'name':'dal',
'team':'red',
'xp':0,
}
];
apiData.forEach((playerJson){
var player = Player.fromJson(playerJson);
player.sayHello();
});
}
class Player{
// 1. type 선언
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(){
// constructor로 생성하고 값을 수정할 때 다음과 같이 수정함
var jh = Player(name:'jh', xp:1200, team:'blue');
jh.name = 'another';
jh.xp = 123182309;
jh.team = 'red';
// Cascade Notation
// 그러나 위와 같은 코드를 아래처럼 수정할 수 있음. 훨씬 더 간편함
var nico = Player(name: 'jh', xp:1200, team:'red')
..name = 'las'
..xp = 120000
..team = 'blue'
..sayHello();
}
enum Team { red, blue }
enum XPLevel {beginner, medium, pro}
class Player{
// 1. type 선언
String name;
XPLevel xp ;
Team team;
Player({required this.name,
required this.xp,
required this.team});
void sayHello(){
print("Hi my name is $name");
}
}
void main(){
// constructor로 생성하고 값을 수정할 때 다음과 같이 수정함
var jh = Player(name:'jh', xp:XPLevel.medium, team:Team.red);
jh.name = 'another';
jh.xp = XPLevel.beginner;
jh.team = Team.red;
// Cascade Notation
// 그러나 위와 같은 코드를 아래처럼 수정할 수 있음. 훨씬 더 간편함
var nico = Player(name: 'jh', xp:XPLevel.beginner, team:Team.blue)
..name = 'las'
..xp = XPLevel.pro
..team = Team.blue
..sayHello();
}
// 추상화 클래스: 다른 클래스들이 직접 구현해야 하는 메소드들을 모아놓은 일정의 청사진
abstract class Human{
void walk();
// Human이라는 추상화 클래스는 walk라는 메소드를 가지고
// return이 없는 void 이다 정도 정의해줌 -> 일종의 청사진
}
enum Team { red, blue }
enum XPLevel {beginner, medium, pro}
class Player extends Human{ // extends: 상속
// 1. type 선언
String name;
XPLevel xp ;
Team team;
Player({required this.name,
required this.xp,
required this.team});
void walk(){
print("im walking");
}
void sayHello(){
print("Hi my name is $name");
}
}
class Coach extends Human{
void walk(){
print("the coach i walking");
}
}
void main(){
// constructor로 생성하고 값을 수정할 때 다음과 같이 수정함
var jh = Player(name:'jh', xp:XPLevel.medium, team:Team.red);
jh.name = 'another';
jh.xp = XPLevel.beginner;
jh.team = Team.red;
// Cascade Notation
// 그러나 위와 같은 코드를 아래처럼 수정할 수 있음. 훨씬 더 간편함
var nico = Player(name: 'jh', xp:XPLevel.beginner, team:Team.blue)
..name = 'las'
..xp = XPLevel.pro
..team = Team.blue
..sayHello();
}
class Human{
final String name;
Human({required this.name});
void sayHello(){
print('Hi my name is $name');
}
}
enum Team { blue, red}
class Player extends Human{
final Team team;
Player({
required this.team,
required String name
}): super(name: name); // super라는 키워드를 통해 부모 클래스와 상호작용 가능
@override
void sayHello(){
super.sayHello();
print('and i play for ${team}');
}
}
void main(){
var player = Player(team: Team.red, name: 'nico');
player.sayHello();
}
mixin class Strong{ // 생성자가 없음
final double strengthLevel = 1500.99;
}
mixin class QuickRunner{ // 생성자가 없음
void runQuick(){
print("ruuuuuuuuun!");
}
}
mixin class Tall{ // 생성자가 없음
final double height = 1.99;
}
class Horse with Strong, QuickRunner{}
class Kid with QuickRunner{}
class Human{
final String name;
Human({required this.name});
void sayHello(){
print('Hi my name is $name');
}
}
enum Team { blue, red}
class Player with Strong, QuickRunner, Tall{
final Team team;
Player({
required this.team,
required String name
});
}
void main(){
var player = Player(team: Team.red, name: 'nico');
player.height; // mixin class 에서 선언한 값에 접근 가능
}
dart 베이스 지식 공부 완료!
Dart 강의 출처: 노마드 코더